473,395 Members | 1,706 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Need Help declaring parameter variables for DllImport for c-dll fu

Hi, I'm using vs2005, .net 2, C# for Windows application. I use DllImport so
I can call up a function written in C++ as unmanaged code and compiled as a
dll us vs2005. My application is able to call the function, EncodeAsnUser.
And it's returning OK but when I display the decoded data in another part of
my application it shows no data has been decoded, all fiedls are either null
or blanks. For some reason, I am not able to step through this function's
code. However, I can see the userContextData does hold all the data that I
assigned and that it's passing.
I think the pbroblems is with my declaration of the parameters(blob and the
userdata structure) .
1. Am I passing the userContextData as a pointer to the function?
2. Am I allocating memory correctly for the Blob?
3. Am I passing the Blob** correctly?
Can someone see what I need to correct here to make it work? Thank you.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class CUserContextData
{
public int bWinLogOn = 0;
public int bUnifiedID = 0;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String shell = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String homeDir = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String primaryGroupSID = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String LoginName = null;

public int symarkUID = 0; //Unified User ID
public int IID = 0; //Independant ID
public int Revision = 0;
}

public struct Blob
{
public IntPtr pData;
public int nLength;
public int nSize;
}

public class LibWrap
{
[DllImport("UnityDecodeAsnUser.dll", CharSet = CharSet.Unicode)]
public static extern DE_ERRORS EncodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);
}

// create an instance of the Blob structure
CUnityDS.Blob blob = new CUnityDS.Blob();
//Encode the user data into a blob
int nBytes = Marshal.SizeOf(typeof(CUnityDS.Blob));
IntPtr ptr = Marshal.AllocHGlobal(nBytes);
// copy and pin the structure to that location
Marshal.StructureToPtr(blob, ptr, true);

// Pass it by reference
// OK, now it's time to "reconsitute" the structure
blob = (CUnityDS.Blob)Marshal.PtrToStructure(ptr,
typeof(CUnityDS.Blob));
CUnityDS.DE_ERRORS errcode =
CUnityDS.DE_ERRORS.DE_MEMORY_ALLOCATION_FAILURE;
errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);

//Convert from IntPtr data to byte[] which is needed
for adding as meetingBlob
int size = Marshal.SizeOf(blob);
byte[] meetingBlob = new byte[size];

System.Runtime.InteropServices.Marshal.Copy(blob.p Data, meetingBlob, 0,
size);
//add the blob

deNewContextObject.Properties["meetingBlob"].Add((object)meetingBlob);

deNewContextObject.CommitChanges();

//This is the C++ function that I'm calling
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
CUserContextData *userData)
{
_bstr_t temp;
AsnData* pAsn;
std::wstring wsUID;
int REVISION=0;
const char* EMPTY_STRING;
EMPTY_STRING = "";

if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
{
DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
return DE_MEMORY_ALLOCATION_FAILURE;
}
if ( !AsnPushTag(pAsn, (ASN_TAG$APPLICATION_START) ) )
goto failed;

if (!AsnWriteInteger( pAsn, REVISION))
goto failed;

if(userData->bUnifiedID)//use UID
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;
}
else //use indep ID
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}
if(userData->IID == NULL)
{
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;
}
else
{
_bstr_t bstrtUID = L"0"; //initilize the bstr
_itow(userData->IID, bstrtUID, 10);

if ( !AsnWriteGeneralString( pAsn, (char*)bstrtUID))
goto failed;
}

//WinUser name
if(userData->bWinLogOn)
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;

}
else//use indep User Name
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}

//Geco
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;

//Shell
temp = userData->shell;
if ( !AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

//Home Driectory
temp = userData->homeDir;
if ( !AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

//Primary Group SID
temp = userData->primaryGroupSID;
if (!AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

if ( !AsnPopTag( pAsn ) )
goto failed;
*ppBlob = AsnExtractData( pAsn );
AsnFree( pAsn );
return DE_SUCCESS;

failed:
DbgLog(DL_ERROR, "Failed to encode ASN.1 message packet" );
AsnFree( pAsn );
return DE_ENCODE_MESSAGE_PACKET_FAILURE;
--
Thanks.
Jun 18 '07 #1
8 2908
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D2**********************************@microsof t.com...
Hi, I'm using vs2005, .net 2, C# for Windows application. I use DllImport
so
I can call up a function written in C++ as unmanaged code and compiled as
a
dll us vs2005. My application is able to call the function,
EncodeAsnUser.
And it's returning OK but when I display the decoded data in another part
of
my application it shows no data has been decoded, all fiedls are either
null
or blanks. For some reason, I am not able to step through this function's
code. However, I can see the userContextData does hold all the data that
I
assigned and that it's passing.
I think the pbroblems is with my declaration of the parameters(blob and
the
userdata structure) .
1. Am I passing the userContextData as a pointer to the function?
2. Am I allocating memory correctly for the Blob?
3. Am I passing the Blob** correctly?
Can someone see what I need to correct here to make it work? Thank you.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class CUserContextData
{
public int bWinLogOn = 0;
public int bUnifiedID = 0;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String shell = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String homeDir = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String primaryGroupSID = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String LoginName = null;

public int symarkUID = 0; //Unified User ID
public int IID = 0; //Independant ID
public int Revision = 0;
}

public struct Blob
{
public IntPtr pData;
public int nLength;
public int nSize;
}

public class LibWrap
{
[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS EncodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);
}

// create an instance of the Blob structure
CUnityDS.Blob blob = new CUnityDS.Blob();
//Encode the user data into a blob
int nBytes = Marshal.SizeOf(typeof(CUnityDS.Blob));
IntPtr ptr = Marshal.AllocHGlobal(nBytes);
// copy and pin the structure to that location
Marshal.StructureToPtr(blob, ptr, true);

// Pass it by reference
// OK, now it's time to "reconsitute" the structure
blob = (CUnityDS.Blob)Marshal.PtrToStructure(ptr,
typeof(CUnityDS.Blob));
CUnityDS.DE_ERRORS errcode =
CUnityDS.DE_ERRORS.DE_MEMORY_ALLOCATION_FAILURE;
errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);

//Convert from IntPtr data to byte[] which is
needed
for adding as meetingBlob
int size = Marshal.SizeOf(blob);
byte[] meetingBlob = new byte[size];

System.Runtime.InteropServices.Marshal.Copy(blob.p Data, meetingBlob, 0,
size);
//add the blob

deNewContextObject.Properties["meetingBlob"].Add((object)meetingBlob);

deNewContextObject.CommitChanges();

//This is the C++ function that I'm calling
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
CUserContextData *userData)
{
_bstr_t temp;
AsnData* pAsn;
std::wstring wsUID;
int REVISION=0;
const char* EMPTY_STRING;
EMPTY_STRING = "";

if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
{
DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
return DE_MEMORY_ALLOCATION_FAILURE;
}
if ( !AsnPushTag(pAsn, (ASN_TAG$APPLICATION_START) ) )
goto failed;

if (!AsnWriteInteger( pAsn, REVISION))
goto failed;

if(userData->bUnifiedID)//use UID
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;
}
else //use indep ID
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}
if(userData->IID == NULL)
{
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;
}
else
{
_bstr_t bstrtUID = L"0"; //initilize the bstr
_itow(userData->IID, bstrtUID, 10);

if ( !AsnWriteGeneralString( pAsn, (char*)bstrtUID))
goto failed;
}

//WinUser name
if(userData->bWinLogOn)
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;

}
else//use indep User Name
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}

//Geco
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;

//Shell
temp = userData->shell;
if ( !AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

//Home Driectory
temp = userData->homeDir;
if ( !AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

//Primary Group SID
temp = userData->primaryGroupSID;
if (!AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

if ( !AsnPopTag( pAsn ) )
goto failed;
*ppBlob = AsnExtractData( pAsn );
AsnFree( pAsn );
return DE_SUCCESS;

failed:
DbgLog(DL_ERROR, "Failed to encode ASN.1 message packet" );
AsnFree( pAsn );
return DE_ENCODE_MESSAGE_PACKET_FAILURE;
--
Thanks.


Pucca, You have a wrong idea abut how the Blob structure looks like.
This struct holds a pointer and two integers, that means it's length is 12
bytes (in a 32 bit application), while you think that this struct holds the
actual data of the blob on return, it just holds a pointer to the data and
(I assume) the length of the actual data in nLength and the length of the
buffer for the data in nSize.

Note that here I assume that the "AsnExtractData" function called in the
EncodeAsnUser function effectively fills the Blob with the data pointer and
the size of the data in the buffer and the size of buffer .

One way to get at the Blob and the Data is shown in the followin:

[DllImport(...]
public static extern DE_ERRORS EncodeAsnUser(ref IntPtr blob, ...
...
// allocate memry for the blob
IntPtr pBlob = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Blob))) ;
// call the function passing the pointer to the blob byref
EncodeAsnUser(ref pBlob, userContextData);
// copy the unmanaged blob to managed struct Blob
Blob blob = (Blob)Marshal.PtrToStructure(pBlob, typeof(Blob));
// allocate byte array with size of blob.nLength
byte[] meetingBlob = new byte[blob.nLength];
// marshal the data pointed to by pData into the byte array
System.Runtime.InteropServices.Marshal.Copy(blob.p Data, meetingBlob, 0,
blob.nLength);
// use the byate array
Willy.
Jun 18 '07 #2
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:OA**************@TK2MSFTNGP05.phx.gbl...
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D2**********************************@microsof t.com...
>Hi, I'm using vs2005, .net 2, C# for Windows application. I use
DllImport so
I can call up a function written in C++ as unmanaged code and compiled as
a
dll us vs2005. My application is able to call the function,
EncodeAsnUser.
And it's returning OK but when I display the decoded data in another part
of
my application it shows no data has been decoded, all fiedls are either
null
or blanks. For some reason, I am not able to step through this
function's
code. However, I can see the userContextData does hold all the data that
I
assigned and that it's passing.
I think the pbroblems is with my declaration of the parameters(blob and
the
userdata structure) .
1. Am I passing the userContextData as a pointer to the function?
2. Am I allocating memory correctly for the Blob?
3. Am I passing the Blob** correctly?
Can someone see what I need to correct here to make it work? Thank you.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class CUserContextData
{
public int bWinLogOn = 0;
public int bUnifiedID = 0;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String shell = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String homeDir = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String primaryGroupSID = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String LoginName = null;

public int symarkUID = 0; //Unified User ID
public int IID = 0; //Independant ID
public int Revision = 0;
}

public struct Blob
{
public IntPtr pData;
public int nLength;
public int nSize;
}

public class LibWrap
{
[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS EncodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);
}

// create an instance of the Blob structure
CUnityDS.Blob blob = new CUnityDS.Blob();
//Encode the user data into a blob
int nBytes =
Marshal.SizeOf(typeof(CUnityDS.Blob));
IntPtr ptr = Marshal.AllocHGlobal(nBytes);
// copy and pin the structure to that location
Marshal.StructureToPtr(blob, ptr, true);

// Pass it by reference
// OK, now it's time to "reconsitute" the
structure
blob = (CUnityDS.Blob)Marshal.PtrToStructure(ptr,
typeof(CUnityDS.Blob));
CUnityDS.DE_ERRORS errcode =
CUnityDS.DE_ERRORS.DE_MEMORY_ALLOCATION_FAILURE ;
errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);

//Convert from IntPtr data to byte[] which is
needed
for adding as meetingBlob
int size = Marshal.SizeOf(blob);
byte[] meetingBlob = new byte[size];

System.Runtime.InteropServices.Marshal.Copy(blob. pData, meetingBlob, 0,
size);
//add the blob

deNewContextObject.Properties["meetingBlob"].Add((object)meetingBlob);

deNewContextObject.CommitChanges();

//This is the C++ function that I'm calling
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
CUserContextData *userData)
{
_bstr_t temp;
AsnData* pAsn;
std::wstring wsUID;
int REVISION=0;
const char* EMPTY_STRING;
EMPTY_STRING = "";

if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
{
DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
return DE_MEMORY_ALLOCATION_FAILURE;
}
if ( !AsnPushTag(pAsn, (ASN_TAG$APPLICATION_START) ) )
goto failed;

if (!AsnWriteInteger( pAsn, REVISION))
goto failed;

if(userData->bUnifiedID)//use UID
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;
}
else //use indep ID
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}
if(userData->IID == NULL)
{
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;
}
else
{
_bstr_t bstrtUID = L"0"; //initilize the bstr
_itow(userData->IID, bstrtUID, 10);

if ( !AsnWriteGeneralString( pAsn, (char*)bstrtUID))
goto failed;
}

//WinUser name
if(userData->bWinLogOn)
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;

}
else//use indep User Name
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}

//Geco
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;

//Shell
temp = userData->shell;
if ( !AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

//Home Driectory
temp = userData->homeDir;
if ( !AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

//Primary Group SID
temp = userData->primaryGroupSID;
if (!AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

if ( !AsnPopTag( pAsn ) )
goto failed;
*ppBlob = AsnExtractData( pAsn );
AsnFree( pAsn );
return DE_SUCCESS;

failed:
DbgLog(DL_ERROR, "Failed to encode ASN.1 message packet" );
AsnFree( pAsn );
return DE_ENCODE_MESSAGE_PACKET_FAILURE;
--
Thanks.

Pucca, You have a wrong idea abut how the Blob structure looks like.
This struct holds a pointer and two integers, that means it's length is 12
bytes (in a 32 bit application), while you think that this struct holds
the actual data of the blob on return, it just holds a pointer to the data
and (I assume) the length of the actual data in nLength and the length of
the buffer for the data in nSize.

Note that here I assume that the "AsnExtractData" function called in the
EncodeAsnUser function effectively fills the Blob with the data pointer
and the size of the data in the buffer and the size of buffer .

One way to get at the Blob and the Data is shown in the followin:

[DllImport(...]
public static extern DE_ERRORS EncodeAsnUser(ref IntPtr blob, ...
...
// allocate memry for the blob
IntPtr pBlob = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Blob))) ;
// call the function passing the pointer to the blob byref
EncodeAsnUser(ref pBlob, userContextData);
// copy the unmanaged blob to managed struct Blob
Blob blob = (Blob)Marshal.PtrToStructure(pBlob, typeof(Blob));
// allocate byte array with size of blob.nLength
byte[] meetingBlob = new byte[blob.nLength];
// marshal the data pointed to by pData into the byte array
System.Runtime.InteropServices.Marshal.Copy(blob.p Data, meetingBlob, 0,
blob.nLength);
// use the byate array
Willy.



Note that when the callee requires the caller to allocate the buffer for the
Data (which I assume is the case), then you need to change to code into
something like:

....
int dataSize = 512; // assume 512 byte buffer
IntPtr pBlob = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Blob))) ;
IntPtr pData = Marshal.AllocHGlobal(dataSize );
Blob blob = new Blob();
blob.nSize = dataSize ;
blob.pData = pData;
Marshal.StructureToPtr(blob, pBlob, true);
EncodeAsnUser(ref pBlob);
// check return value from function
// and proceed is success...
blob = (Blob)Marshal.PtrToStructure(pBlob, typeof(Blob));
// assuming nLength is the size in bytes returned in the buffer pointed
to by pData!!
byte[] meetingBlob = new byte[blob.nLength];
Marshal.Copy(blob.pData, meetingBlob, 0, blob.nLength);
// use data in meetingBlob here...
// Free allocated memory!
Marshal.FreeHGlobal(pBlob);
Marshal.FreeHGlobal(pData);
Willy.

Jun 18 '07 #3
Hi Willy ,
What you said about the nSize and nLength makes a lot of sense. You're also
right about the pointer to the encoded data pointed by a pointer in the Blob
struc. However, the length of the data is not return by AsnExtractData(code
listed below).
I am getting compliation error with my current code below. I'm getting
error message below. Can you see what I need to correct here? Thank you.

- cannot convert from 'ref System.IntPtr' to 'ref UnityLib.CUnityDS.Blob'
- The best overloaded method match for
UnityLib.CUnityDS.LibWrap.EncodeAsnUser(ref UnityLib.CUnityDS.Blob,
UnityLib.CUnityDS.CUserContextData)' has some invalid arguments

int dataSize = 512; // assume 512 byte buffer
IntPtr pBlob = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CUnityD S.Blob)));
IntPtr pData = Marshal.AllocHGlobal(dataSize );
//CUnityDS.Blob blob = new CUnityDS.Blob();
blob.nSize = dataSize ;
blob.pData = pData;
Marshal.StructureToPtr(blob, pBlob, true);
CUnityDS.LibWrap.EncodeAsnUser(ref pBlob, userContextData);
// check return value from function
// and proceed is success...
blob = (CUnityDS.Blob)Marshal.PtrToStructure(pBlob, typeof(CUnityDS.Blob));
// assuming nLength is the size in bytes returned in the buffer pointed to
by pData!!
byte[] meetingBlob = new byte[blob.nLength];
Marshal.Copy(blob.pData, meetingBlob, 0, blob.nLength);
// use data in meetingBlob here...
// Free allocated memory!
Marshal.FreeHGlobal(pBlob);
Marshal.FreeHGlobal(pData);

-- Blob *
AsnExtractData( AsnData *pAsn )
{
Blob *p;

if ( pAsn == NULL )
return NULL;

p = pAsn->pBlob;
pAsn->pBlob = NULL;

return p;
}
Thanks.
"Willy Denoyette [MVP]" wrote:
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:D2**********************************@microsof t.com...
Hi, I'm using vs2005, .net 2, C# for Windows application. I use DllImport
so
I can call up a function written in C++ as unmanaged code and compiled as
a
dll us vs2005. My application is able to call the function,
EncodeAsnUser.
And it's returning OK but when I display the decoded data in another part
of
my application it shows no data has been decoded, all fiedls are either
null
or blanks. For some reason, I am not able to step through this function's
code. However, I can see the userContextData does hold all the data that
I
assigned and that it's passing.
I think the pbroblems is with my declaration of the parameters(blob and
the
userdata structure) .
1. Am I passing the userContextData as a pointer to the function?
2. Am I allocating memory correctly for the Blob?
3. Am I passing the Blob** correctly?
Can someone see what I need to correct here to make it work? Thank you.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class CUserContextData
{
public int bWinLogOn = 0;
public int bUnifiedID = 0;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String shell = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String homeDir = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String primaryGroupSID = null;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst =
MAX_ADSPATH_CHARS)]
public String LoginName = null;

public int symarkUID = 0; //Unified User ID
public int IID = 0; //Independant ID
public int Revision = 0;
}

public struct Blob
{
public IntPtr pData;
public int nLength;
public int nSize;
}

public class LibWrap
{
[DllImport("UnityDecodeAsnUser.dll", CharSet =
CharSet.Unicode)]
public static extern DE_ERRORS EncodeAsnUser(ref Blob blob,
[In, Out]CUserContextData m);
}

// create an instance of the Blob structure
CUnityDS.Blob blob = new CUnityDS.Blob();
//Encode the user data into a blob
int nBytes = Marshal.SizeOf(typeof(CUnityDS.Blob));
IntPtr ptr = Marshal.AllocHGlobal(nBytes);
// copy and pin the structure to that location
Marshal.StructureToPtr(blob, ptr, true);

// Pass it by reference
// OK, now it's time to "reconsitute" the structure
blob = (CUnityDS.Blob)Marshal.PtrToStructure(ptr,
typeof(CUnityDS.Blob));
CUnityDS.DE_ERRORS errcode =
CUnityDS.DE_ERRORS.DE_MEMORY_ALLOCATION_FAILURE;
errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);

//Convert from IntPtr data to byte[] which is
needed
for adding as meetingBlob
int size = Marshal.SizeOf(blob);
byte[] meetingBlob = new byte[size];

System.Runtime.InteropServices.Marshal.Copy(blob.p Data, meetingBlob, 0,
size);
//add the blob

deNewContextObject.Properties["meetingBlob"].Add((object)meetingBlob);

deNewContextObject.CommitChanges();

//This is the C++ function that I'm calling
extern "C" DE_ERRORS __declspec(dllexport)EncodeAsnUser(Blob** ppBlob,
CUserContextData *userData)
{
_bstr_t temp;
AsnData* pAsn;
std::wstring wsUID;
int REVISION=0;
const char* EMPTY_STRING;
EMPTY_STRING = "";

if ( ( pAsn = AsnAlloc( NULL ) ) == NULL )
{
DbgLog( DL_ERROR, "Unable to allocate ASN.1 buffer" );
return DE_MEMORY_ALLOCATION_FAILURE;
}
if ( !AsnPushTag(pAsn, (ASN_TAG$APPLICATION_START) ) )
goto failed;

if (!AsnWriteInteger( pAsn, REVISION))
goto failed;

if(userData->bUnifiedID)//use UID
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;
}
else //use indep ID
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}
if(userData->IID == NULL)
{
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;
}
else
{
_bstr_t bstrtUID = L"0"; //initilize the bstr
_itow(userData->IID, bstrtUID, 10);

if ( !AsnWriteGeneralString( pAsn, (char*)bstrtUID))
goto failed;
}

//WinUser name
if(userData->bWinLogOn)
{
if (!AsnWriteInteger( pAsn, True) )
goto failed;

}
else//use indep User Name
{
if (!AsnWriteInteger( pAsn, False) )
goto failed;
}

//Geco
if ( !AsnWriteGeneralString( pAsn, EMPTY_STRING))
goto failed;

//Shell
temp = userData->shell;
if ( !AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

//Home Driectory
temp = userData->homeDir;
if ( !AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

//Primary Group SID
temp = userData->primaryGroupSID;
if (!AsnWriteGeneralString( pAsn, (char*)temp))
goto failed;

if ( !AsnPopTag( pAsn ) )
goto failed;
*ppBlob = AsnExtractData( pAsn );
AsnFree( pAsn );
return DE_SUCCESS;

failed:
DbgLog(DL_ERROR, "Failed to encode ASN.1 message packet" );
AsnFree( pAsn );
return DE_ENCODE_MESSAGE_PACKET_FAILURE;
--
Thanks.

Pucca, You have a wrong idea abut how the Blob structure looks like.
This struct holds a pointer and two integers, that means it's length is 12
bytes (in a 32 bit application), while you think that this struct holds the
actual data of the blob on return, it just holds a pointer to the data and
(I assume) the length of the actual data in nLength and the length of the
buffer for the data in nSize.

Note that here I assume that the "AsnExtractData" function called in the
EncodeAsnUser function effectively fills the Blob with the data pointer and
the size of the data in the buffer and the size of buffer .

One way to get at the Blob and the Data is shown in the followin:

[DllImport(...]
public static extern DE_ERRORS EncodeAsnUser(ref IntPtr blob, ...
...
// allocate memry for the blob
IntPtr pBlob = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Blob))) ;
// call the function passing the pointer to the blob byref
EncodeAsnUser(ref pBlob, userContextData);
// copy the unmanaged blob to managed struct Blob
Blob blob = (Blob)Marshal.PtrToStructure(pBlob, typeof(Blob));
// allocate byte array with size of blob.nLength
byte[] meetingBlob = new byte[blob.nLength];
// marshal the data pointed to by pData into the byte array
System.Runtime.InteropServices.Marshal.Copy(blob.p Data, meetingBlob, 0,
blob.nLength);
// use the byate array
Willy.
Jun 18 '07 #4
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:8C**********************************@microsof t.com...
Hi Willy ,
What you said about the nSize and nLength makes a lot of sense. You're
also
right about the pointer to the encoded data pointed by a pointer in the
Blob
struc. However, the length of the data is not return by
AsnExtractData(code
listed below).
I am getting compliation error with my current code below. I'm getting
error message below. Can you see what I need to correct here? Thank you.

- cannot convert from 'ref System.IntPtr' to 'ref
UnityLib.CUnityDS.Blob'
- The best overloaded method match for
UnityLib.CUnityDS.LibWrap.EncodeAsnUser(ref UnityLib.CUnityDS.Blob,
UnityLib.CUnityDS.CUserContextData)' has some invalid arguments

int dataSize = 512; // assume 512 byte buffer
IntPtr pBlob =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CUnityD S.Blob)));
IntPtr pData = Marshal.AllocHGlobal(dataSize );
//CUnityDS.Blob blob = new CUnityDS.Blob();
blob.nSize = dataSize ;
blob.pData = pData;
Marshal.StructureToPtr(blob, pBlob, true);
CUnityDS.LibWrap.EncodeAsnUser(ref pBlob, userContextData);
// check return value from function
// and proceed is success...
blob = (CUnityDS.Blob)Marshal.PtrToStructure(pBlob,
typeof(CUnityDS.Blob));
// assuming nLength is the size in bytes returned in the buffer pointed to
by pData!!
byte[] meetingBlob = new byte[blob.nLength];
Marshal.Copy(blob.pData, meetingBlob, 0, blob.nLength);
// use data in meetingBlob here...
// Free allocated memory!
Marshal.FreeHGlobal(pBlob);
Marshal.FreeHGlobal(pData);

-- Blob *
AsnExtractData( AsnData *pAsn )
{
Blob *p;

if ( pAsn == NULL )
return NULL;

p = pAsn->pBlob;
pAsn->pBlob = NULL;

return p;
}
Thanks.

UnityLib.CUnityDS.LibWrap.EncodeAsnUser(ref UnityLib.CUnityDS.Blob,
UnityLib.CUnityDS.CUserContextData)' has some invalid arguments

should read:

UnityLib.CUnityDS.LibWrap.EncodeAsnUser(ref IntPtr,
UnityLib.CUnityDS.CUserContextData)' has some invalid arguments

Don't know who has written the C++ function, I would definitely ask for a
rewrite, anyway it needs to return the length of the Data in the blob,
otherwise there is no way to correctly marshal the data back at the caller
side.

Willy.

Jun 18 '07 #5
Hi Willy,
I step through my C++ program that calls the same function, EncodeAsnUser,
and it does returns the nLength, data length when it returns encoding data
into the blob. I think if I am passing in the correct parameters then the
nLength will be set.
Sorry that i copy the error message incorrectly but you got it right there.
It doesn't like the pBlob that I'm declaring and passing. How should I
correct this? Thank you.
--
Thanks.
"Willy Denoyette [MVP]" wrote:
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:8C**********************************@microsof t.com...
Hi Willy ,
What you said about the nSize and nLength makes a lot of sense. You're
also
right about the pointer to the encoded data pointed by a pointer in the
Blob
struc. However, the length of the data is not return by
AsnExtractData(code
listed below).
I am getting compliation error with my current code below. I'm getting
error message below. Can you see what I need to correct here? Thank you.

- cannot convert from 'ref System.IntPtr' to 'ref
UnityLib.CUnityDS.Blob'
- The best overloaded method match for
UnityLib.CUnityDS.LibWrap.EncodeAsnUser(ref UnityLib.CUnityDS.Blob,
UnityLib.CUnityDS.CUserContextData)' has some invalid arguments

int dataSize = 512; // assume 512 byte buffer
IntPtr pBlob =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CUnityD S.Blob)));
IntPtr pData = Marshal.AllocHGlobal(dataSize );
//CUnityDS.Blob blob = new CUnityDS.Blob();
blob.nSize = dataSize ;
blob.pData = pData;
Marshal.StructureToPtr(blob, pBlob, true);
CUnityDS.LibWrap.EncodeAsnUser(ref pBlob, userContextData);
// check return value from function
// and proceed is success...
blob = (CUnityDS.Blob)Marshal.PtrToStructure(pBlob,
typeof(CUnityDS.Blob));
// assuming nLength is the size in bytes returned in the buffer pointed to
by pData!!
byte[] meetingBlob = new byte[blob.nLength];
Marshal.Copy(blob.pData, meetingBlob, 0, blob.nLength);
// use data in meetingBlob here...
// Free allocated memory!
Marshal.FreeHGlobal(pBlob);
Marshal.FreeHGlobal(pData);

-- Blob *
AsnExtractData( AsnData *pAsn )
{
Blob *p;

if ( pAsn == NULL )
return NULL;

p = pAsn->pBlob;
pAsn->pBlob = NULL;

return p;
}
Thanks.


UnityLib.CUnityDS.LibWrap.EncodeAsnUser(ref UnityLib.CUnityDS.Blob,
UnityLib.CUnityDS.CUserContextData)' has some invalid arguments

should read:

UnityLib.CUnityDS.LibWrap.EncodeAsnUser(ref IntPtr,
UnityLib.CUnityDS.CUserContextData)' has some invalid arguments

Don't know who has written the C++ function, I would definitely ask for a
rewrite, anyway it needs to return the length of the Data in the blob,
otherwise there is no way to correctly marshal the data back at the caller
side.

Willy.

Jun 18 '07 #6
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:CB**********************************@microsof t.com...
Hi Willy,
I step through my C++ program that calls the same function, EncodeAsnUser,
and it does returns the nLength, data length when it returns encoding data
into the blob. I think if I am passing in the correct parameters then the
nLength will be set.
Sorry that i copy the error message incorrectly but you got it right
there.
It doesn't like the pBlob that I'm declaring and passing. How should I
correct this? Thank you.
--
I can't help you if you don't post *all* of the relevant part of the code,
together with the DllImport declaration of the function you call.
Also you need to tell us what exactly is the error, after you have changed
the first argument into a "ref IntPtr" !!.
Willy.

Jun 18 '07 #7
Very sorry Willy. Sometimes I wonder how much code should I post. It just
seems like a lot but I'll post them all in the future. Here are all the C++
functions called by the AsnEncodeUser function. Also, here is my current
code. I modify to pass only the blob as the parameter. It gets rid of the
compiling error but I'm still getting back 0 nlength after Encode. thank
you.
errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob, userContextData);

//current code
int dataSize = 512; // assume 512 byte buffer
IntPtr pBlob =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof (CUnityDS.Blob)));
IntPtr pData = Marshal.AllocHGlobal(dataSize );
//CUnityDS.Blob blob = new CUnityDS.Blob();
blob.nSize = dataSize ;
blob.pData = pData;
Marshal.StructureToPtr(blob, pBlob, true);
// check return value from function
CUnityDS.DE_ERRORS errcode =
CUnityDS.DE_ERRORS.DE_MEMORY_ALLOCATION_FAILURE;
errcode = CUnityDS.LibWrap.EncodeAsnUser(ref blob,
userContextData);
if (errcode != CUnityDS.DE_ERRORS.DE_SUCCESS)
result = false;
else
{
blob =
(CUnityDS.Blob)Marshal.PtrToStructure(pBlob, typeof(CUnityDS.Blob));
// nLength is the size in bytes returned in the
buffer pointed to by pData!!
// use data in meetingBlob
byte[] meetingBlob = new byte[blob.nLength];
Marshal.Copy(blob.pData, meetingBlob, 0,
blob.nLength);
// Free allocated memory!
Marshal.FreeHGlobal(pBlob);
Marshal.FreeHGlobal(pData);
//add the blob

deNewContextObject.Properties["meetingBlob"].Add((object)meetingBlob);

deNewContextObject.CommitChanges();
//Additional C++ fucnctions called by AsnEncodeUser
AsnData *
AsnAlloc( Blob * pBlob )
{
AsnData * pAsn;

pAsn = (AsnData *)calloc(1, sizeof(AsnData));
if ( pAsn == NULL )
return NULL;

if ( pBlob )
pAsn->pBlob = BlobClone( pBlob );
else
pAsn->pBlob = BlobAlloc( NULL, 256 );

if ( pAsn->pBlob == NULL )
{
free( pAsn );
return NULL;
}

return pAsn;
}

Bool
AsnPushTag(AsnData *pAsn, ASN_TAG tag)
{
AsnNode *pNode;

if (!AsnWriteByte(pAsn, tag))
return False;

pNode = (AsnNode*)calloc(1, sizeof(AsnNode));
if (!pNode)
return False;

pNode->nStart = BlobGetLength(pAsn->pBlob);
pNode->pNext = pAsn->pNode;
pAsn->pNode = pNode;

return AsnWriteByte(pAsn, 0); /* placeholder for length */
}

Bool
AsnWriteInteger(AsnData *pAsn, int nValue)
{
int i = 0;
Bit8 szBuf[sizeof(nValue)];

if (!AsnPushTag(pAsn, ASN_TAG$INTEGER))
return False;

/* Make sure we store the integer in an endian neutral form */
do
{
szBuf[i++] = nValue & 0xFF;
nValue >>= 8;
} while ( nValue );

do
{
if (!AsnWriteByte(pAsn, szBuf[--i]))
return False;
} while ( i );

return AsnPopTag(pAsn);
}
Bool
AsnWriteGeneralString(AsnData *pAsn, const char *p)
{
return (((AsnPushTag(pAsn, ASN_TAG$GENERAL_STRING)==True) &&
(AsnWrite(pAsn, p, strlen(p))==True) &&
(AsnPopTag(pAsn)==True)
)==True) ? True : False;
}
Bool
AsnPopTag(AsnData *pAsn)
{
AsnNode *pNode;
Bit32 nLength;

pNode = pAsn->pNode;

if (!pNode)
return False;

nLength = BlobGetLength(pAsn->pBlob) - (pNode->nStart + 1);

/* Now we can go back and write the actual length of the node */
if ( nLength <= 127 )
pAsn->pBlob->pData[pNode->nStart] = nLength;
else if ( nLength <= 255 )
{
/* We need to write a two-byte length - make sure we have room */
if (!AsnWriteByte(pAsn, 0))
return False;

/* Move data down one byte */
memmove(pAsn->pBlob->pData + pNode->nStart + 2,
pAsn->pBlob->pData + pNode->nStart + 1,
nLength);

pAsn->pBlob->pData[pNode->nStart ] = 0x81;
pAsn->pBlob->pData[pNode->nStart + 1] = nLength;
}
else
{
/* We need to write a three-byte length - make sure we have room */
if (!AsnWriteByte(pAsn, 0))
return False;
if (!AsnWriteByte(pAsn, 0))
return False;

/* Move data down two bytes */
memmove(pAsn->pBlob->pData + pNode->nStart + 3,
pAsn->pBlob->pData + pNode->nStart + 1,
nLength);

pAsn->pBlob->pData[pNode->nStart ] = 0x82;
pAsn->pBlob->pData[pNode->nStart + 1] = nLength >8;
pAsn->pBlob->pData[pNode->nStart + 2] = nLength & 0xff;
}

pAsn->pNode = pNode->pNext;
free(pNode);

return True;
}
Blob *
AsnExtractData( AsnData *pAsn )
{
Blob *p;

if ( pAsn == NULL )
return NULL;

p = pAsn->pBlob;
pAsn->pBlob = NULL;

return p;
}
--
Thanks.
"Willy Denoyette [MVP]" wrote:
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:CB**********************************@microsof t.com...
Hi Willy,
I step through my C++ program that calls the same function, EncodeAsnUser,
and it does returns the nLength, data length when it returns encoding data
into the blob. I think if I am passing in the correct parameters then the
nLength will be set.
Sorry that i copy the error message incorrectly but you got it right
there.
It doesn't like the pBlob that I'm declaring and passing. How should I
correct this? Thank you.
--

I can't help you if you don't post *all* of the relevant part of the code,
together with the DllImport declaration of the function you call.
Also you need to tell us what exactly is the error, after you have changed
the first argument into a "ref IntPtr" !!.
Willy.

Jun 18 '07 #8
Hi Willy,
I can't thank you enough for helping me with this difficult problem. It is
now working! You were right from the very 1st posting. The function takes
care of allocating all the memory for the data so I don't need to allocating
any memory except for the pointer that I'm passing as you have it in your
first example. It didn't work the 1st time because, 1, I used your 2nd
example where we allocate all the memory. And 2, I missed the change in the
declaration of "ref IntPtr blob" as shown below. That made all the
difference. Now all my data are showing up correctly. Thank you and thank
you again!

DllImport(...]
public static extern DE_ERRORS EncodeAsnUser(ref IntPtr blob, ...
--
Thanks.
"Willy Denoyette [MVP]" wrote:
"Pucca" <Pu***@discussions.microsoft.comwrote in message
news:CB**********************************@microsof t.com...
Hi Willy,
I step through my C++ program that calls the same function, EncodeAsnUser,
and it does returns the nLength, data length when it returns encoding data
into the blob. I think if I am passing in the correct parameters then the
nLength will be set.
Sorry that i copy the error message incorrectly but you got it right
there.
It doesn't like the pBlob that I'm declaring and passing. How should I
correct this? Thank you.
--

I can't help you if you don't post *all* of the relevant part of the code,
together with the DllImport declaration of the function you call.
Also you need to tell us what exactly is the error, after you have changed
the first argument into a "ref IntPtr" !!.
Willy.

Jun 18 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Oliver Corona | last post by:
I am wondering if anyone has any insights on the performance benefit (or detriment) of declaring local variables instead of referencing members. Is allocating memory for a new variable more...
3
by: jcrouse | last post by:
The syntax for a public variable seems to be "Public Shared name As type". How AND where do I put these in my AppMain (startup module) so the can be used by two different forms Thanks John
1
by: swapnarani29 | last post by:
how can i decalre global variables in javascript so that the value which is held by global variable is carried to and fro between html pages to display some items based upon the value in the global...
2
by: majel | last post by:
I just read an older post that described declaring global variables. I tried this but I'm getting an error and the text stays red. What am I doing wrong? This code is behind a form. Thanks. ...
5
by: Patrick | last post by:
Hi all, In my SQL procedures in DB2 8.2, I current declare several cursors that return select statements with 10 columns in it. As a result, assigning host variables becomes a coding mess, as...
8
by: SM | last post by:
I've always wonder if there is diference when declaring and initializing a varible inside/outside a loop. What's a better practice? Declaring and initializing variables inside a loop routine,...
0
by: devisree | last post by:
what is the purpose of using level number 49 in dynamic sql for declaring group variales?
3
by: Anil Gupte | last post by:
I am using the followig code: SqlConnection con = new SqlConnection(strcon); con.Open(); string strSelect = "Select PaidUntil from Users where username='" + un + "'"; SqlCommand cmd = new...
4
by: Sister Ray | last post by:
I've searched for a way to this in a lot of forums. Haven't found a solution for this, however I've found a work around. Declaring a public object and then adding the variables i want as members...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.