PInvokeStackImbalance error calling MCardConnect


I am getting this error -

A call to PInvoke function 'SmartCardReader!SmartCardReader.SmartCardForm::MCardConnect' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

This is a VB6 to C# conversion for a Smart Card Reader application. The card contains personal login >information. Here is the code.

C# declaration 1:

[DllImport("MCSCM.dll", EntryPoint = "MCardInitialize", CallingConvention = CallingConvention.StdCall)]
static extern int MCardInitialize(
    IntPtr hScardContext, 
    string cReaderName,
    ref long phMCardContext,
    ref long pdwDLLVersion

VB 6 declaration 1:

private long MCardInitialize Lib "MCSCM.DLL" (
    ByVal hSCardContext As Long,
    ByVal scReaderName As String,
    ByRef phMCardContext As Long,
    ByRef pdwDLLVersion As Long

C# declaration 2:

[DllImport("MCSCM.dll", EntryPoint = "MCardConnect", CallingConvention = CallingConvention.StdCall)]
static extern int MCardConnect(
    IntPtr hMCardContext,
    long dwConnectMode,
    byte byCardType,
    ref long phMCard

VB 6 declaration 2:

private long MCardConnect Lib "MCSCM.DLL" (
    ByVal hMCardContext As Long,
    ByVal dwConnectMode As Long,
    ByVal byCardType As Byte,
    ByRef phMCard As Long

I tried “Cdecl” and “ThisCall” for the CallingConvention and got the same error. I tried using the VB 6 declaration and got the same error.

C# call:

public long MCARDTYPE_AT24C16SC = 12; // 0xC; // &HC;  // AT24C16SC memory smartcard 
private System.IntPtr mhSCardCtx;
int iReturn = -1; //  Can not initialize to 0.  0 is the return value for success.
long hMCardCtx = 0;

iReturn = MCardInitialize(mhSCardCtx, sReaderName, ref hMCardCtx, ref dwDLLVersion); 
Return values:
iReturn = 0
mhSCardCtx = “0vCD010000”
sReaderName = “SCM Microsystems Inc. SCR33x USB Smart Card Reader 0”
hMCardCtx = 1
dwDLLVersion = 9 

This is the line that gets the error:

iReturn = MCardConnect((IntPtr)hMCardCtx, mclsGlobal.MCARD_FORCED_MODE, Convert.ToByte(mclsGlobal.MCARDTYPE_AT24C16SC), ref hMCard); 

I changed long to int and got passed that error. Thank you.

The "hMCard" value being returned from the code above is a large negative number. I assume 0 would be a good value.

I changed the declarations and calls to use "IntPtr", but still got a large negative number.

The return value from the function is 0 (success). When the code tries to run the MCardReadMemory function, it causes a fatal error.

Managed Debugging Assistant 'FatalExecutionEngineError' Message=Managed Debugging Assistant 'FatalExecutionEngineError' : 'The runtime has encountered a fatal error. The address of the error was at 0x6fec4ba1, on thread 0x2a3b8. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.'

Here is the call that gets this error:

lReturn = MCardReadMemory(hMCard, 0, 32, ref byCardData, ref uiDataSize);

The value of hMCard is 0xEA010000. The value of byCardData and uiDatasize is 138.

Here is the call that returns the incorrect "hMCard" value but 0 as a successful overall return for the function:

iReturn = MCardConnect(hMCardCtx, mclsGlobal.MCARD_FORCED_MODE, Convert.ToByte(mclsGlobal.MCARDTYPE_AT24C16SC), ref hMCard);

The value of hMCardCtx is - 0x00000001 The value of MCARD_FORCED_MODE is - 0 The value of MCARDTYPE_AT24C16SC is - 12 The value of hMCard is - 0x00000000 (IntPtr.Zero) The return value of iReturn is 0 (success) The return value of hMCard is 0xEA010000 The function uses Forced Mode, because Intelligent Mode can damage the data on the card.

Here are the declarations for these functions:

[DllImport("MCSCM.dll", EntryPoint = "MCardConnect", CallingConvention = CallingConvention.StdCall)]
static extern int MCardConnect(
    IntPtr hMCardContext,
    int dwConnectMode,
    byte byCardType,
    ref IntPtr phMCard

[DllImportAttribute("MCSCM.dll", EntryPoint = "MCardReadMemory", CallingConvention = CallingConvention.StdCall)]
static extern int MCardReadMemory(
    IntPtr hMCard,
    byte bMemZone,
    uint dwOffset,
    ref byte pbReadBuffer,
    ref uint pbReadLen

asked on Stack Overflow Dec 9, 2019 by Kraig Kuusinen • edited Dec 11, 2019 by Kraig Kuusinen

0 Answers

Nobody has answered this question yet.

User contributions licensed under CC BY-SA 3.0