By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,463 Members | 2,858 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,463 IT Pros & Developers. It's quick & easy.

Marshaling Problem when calling API function! Please help!

P: n/a
I want to integrate SecurID two-factor authentication system of the
RSASecurity.inc into our asp.net application,but I get into trouble when
trying to call the API functions of the ACE Agent,I got an error message
saying "Cannot marshal parameter #2: Invalid managed/unmanaged type
combination (this value type must be paired with Struct)" when calling
"AceGetPinParams(iHandle,ref sd_pin)" function,here's my test code:
[DllImport("aceclnt")]
private static extern bool AceInitialize();

[DllImport("aceclnt")]
private static extern int SD_Init(ref IntPtr iHandle);

[DllImport("aceclnt")]
private static extern int SD_Close(IntPtr iHandle);

[DllImport("aceclnt")]
private static extern int SD_Lock(IntPtr iHandle,string uname);

[DllImport("aceclnt")]
private static extern int SD_Check(IntPtr iHandle,string passwd,string
uname);

[DllImport("aceclnt")]
private static extern int SD_Pin(IntPtr iHandle,string pin);

[DllImport("aceclnt")]
private static extern int AceGetPinParams(IntPtr iHandle,ref SD_PinParams
pin);
private void button1_Click(object sender, System.EventArgs e)
{
AuthStatus aStatus=AuthStatus.InitFailed;
if(AceInitialize())//Initialize succeeded
{
int statusCode;
aStatus=AuthStatus.CommunicationFailed;
IntPtr iHandle=new IntPtr(0);
statusCode=SD_Init(ref iHandle);
if(statusCode==0)//Communication with the auth server succeeded
{
aStatus=AuthStatus.AccessDenied;
statusCode=SD_Lock(iHandle,uname.Text);//user has been locked
if(statusCode==0)
{
statusCode=SD_Check(iHandle,pwd.Text,uname.Text);
aStatus=(AuthStatus)statusCode;
if(aStatus==AuthStatus.NewPinRequired)
{
MessageBox.Show("New Pin Required£¡");
SD_PinParams sd_pin=new SD_PinParams();
int i=AceGetPinParams(iHandle,ref sd_pin);
if(i==1)
{
MessageBox.Show(sd_pin.Min.ToString());
MessageBox.Show(sd_pin.Selectable.ToString());
}
}
}

}
SD_Close(iHandle);
}
}

public const int LENPRNST = 16;
[StructLayout(LayoutKind.Sequential)]
public struct SD_PinParams
{
public byte Min;
public byte Max;
public byte Selectable;
public byte Alphanumeric;
[MarshalAs(UnmanagedType.LPArray, SizeConst=LENPRNST+2)]
public byte[] System;
}
public enum AuthStatus
{
InitFailed=1000,//Initialize Failed
CommunicationFailed=1001,//Communication failed
NextCodeRequired=2,//Next token code required
NewPinRequired=5,//New Pin required
Succeeded=0,//Authentication succeeded
AccessDenied=1,//Access denied
InvalidPassCode=902,//Invalid passcode
InvalidUserName901,//Invalid user name
InvalidHandle=101,//Invalid handle
}

public enum NewPinStatus
{
InvalidPin=800,//Invalid pin
Accepted=6,//new pin accepted
Rejected=7,//new pin rejected
InvalidHandle=101,//invalid handle
}
Here's the description of the ACEGetPinParams API function:

Description

int WINAPI AceGetPinParams(
SDI_HANDLE Sdi_handle,
SD_PIN *val)

typedef struct{
SD_CHAR Min;
SD_CHAR Max;
SD_CHAR Selectable;
SD_CHAR Alphanumeric;
SD_CHAR System[LENPRNST+2];
}SD_PIN
The AceGetPinParams function obtains all of the PIN-related parameters at
once. It is
helpful to retrieve this value when the result code from AceCheck is
ACM_NEW_PIN_REQUIRED and the Agent is designed to validate that the new PIN
entered by the user conforms to the required PIN characteristics set by the
RSA ACE/Server
administrator. Any such checking done by the Agent is simply as a
convenience to the user.
The PIN will be fully checked for correctness by the RSA ACE/Server.
Architecture
The caller of this synchronous function must supply, as the second argument,
a pointer to a
structure of type SD_PIN, into which the function will copy the PIN
parameters.
AceGetPinParams does not allocate storage for the data on its own.
Input Arguments
SdiHandle The value of a handle originally assigned by a call to AceInit.
Val A pointer to a structure of type SD_PIN that will contain
copies of the PIN parameters.
Outputs and Post Conditions
The function returns ACE_SUCCESS if the handle to the authentication data
was found and
the PIN value was provided by the function.
Error Handling
A value of ACE_ERR_INVALID_HANDLE is returned if the handle to the
authentication
data cannot be found.

//type definition

typedef int SDI_HANDLE, * LP_SDI_HANDLE;
typedef char SD_CHAR; /* ch or sz */

#define LENPRNST 16

How can I solve this problem,any help will be greatly appreciated!
Nov 15 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
[StructLayout(LayoutKind.Sequential)]
public struct SD_PinParams
{
public byte Min;
public byte Max;
public byte Selectable;
public byte Alphanumeric;
[MarshalAs(UnmanagedType.LPArray, SizeConst=LENPRNST+2)]
public byte[] System;
}


You can't use LPArray this way. If the member really is a pointer to
the array, use IntPtr as its type. If it's an inline array, use
UnmanagedType.ByValArray instead.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 15 '05 #2

P: n/a
Thank you very much,I changed byte[] to IntPtr and it works!!
Thanks again!!
"Mattias Sjögren" <ma********************@mvps.org>
??????:#U**************@TK2MSFTNGP10.phx.gbl...
[StructLayout(LayoutKind.Sequential)]
public struct SD_PinParams
{
public byte Min;
public byte Max;
public byte Selectable;
public byte Alphanumeric;
[MarshalAs(UnmanagedType.LPArray, SizeConst=LENPRNST+2)]
public byte[] System;
}


You can't use LPArray this way. If the member really is a pointer to
the array, use IntPtr as its type. If it's an inline array, use
UnmanagedType.ByValArray instead.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 15 '05 #3

P: n/a
Thank you very much,I changed type[] to IntPtr and it works!!
"Mattias Sjögren" <ma********************@mvps.org>
??????:#U**************@TK2MSFTNGP10.phx.gbl...
[StructLayout(LayoutKind.Sequential)]
public struct SD_PinParams
{
public byte Min;
public byte Max;
public byte Selectable;
public byte Alphanumeric;
[MarshalAs(UnmanagedType.LPArray, SizeConst=LENPRNST+2)]
public byte[] System;
}


You can't use LPArray this way. If the member really is a pointer to
the array, use IntPtr as its type. If it's an inline array, use
UnmanagedType.ByValArray instead.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 15 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.