Click here to Skip to main content
15,887,027 members
Home / Discussions / C#
   

C#

 
GeneralRe: how to implement this code for multiple clients using c sharp Pin
PIEBALDconsult23-Jan-16 9:24
mvePIEBALDconsult23-Jan-16 9:24 
AnswerSimple answer: add an header before data Pin
Philippe Mori23-Jan-16 8:21
Philippe Mori23-Jan-16 8:21 
AnswerRe: how to implement this code for multiple clients using c sharp Pin
jschell27-Jan-16 9:18
jschell27-Jan-16 9:18 
Questionautomatic test data generators for C# ? Pin
BillWoodruff21-Jan-16 18:15
professionalBillWoodruff21-Jan-16 18:15 
AnswerRe: automatic test data generators for C# ? Pin
Eddy Vluggen22-Jan-16 6:38
professionalEddy Vluggen22-Jan-16 6:38 
GeneralRe: automatic test data generators for C# ? Pin
BillWoodruff22-Jan-16 13:03
professionalBillWoodruff22-Jan-16 13:03 
GeneralRe: automatic test data generators for C# ? Pin
Eddy Vluggen23-Jan-16 0:55
professionalEddy Vluggen23-Jan-16 0:55 
QuestionICustomMarshaler not returning an Out parameter Pin
mavl21-Jan-16 5:16
mavl21-Jan-16 5:16 
I have already asked this question on the MSDN Community, but I haven't gotten an answer yet, so I hope the people here can help me.

As a little test project I wrote an ICustomMarshaler, but it's not behaving as I expected. The complete project can be downloaded as zip from my OneDrive.

I'm trying to work with 2 functions from Crypt32.dll which I import in my code:
C#
[DllImport("Crypt32.dll", SetLastError = true)]
private static extern bool CryptProtectData([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ByteArrayToDataBlobMarshaler))] byte[] pDataIn, [Optional] string szDataDescr, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ByteArrayToDataBlobMarshaler)), Optional] byte[] pOptionalEntropy, IntPtr pvReserved, [Optional] IntPtr pPromptStruct, int dwFlags, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ByteArrayToDataBlobMarshaler)), Out] byte[] pDataOut);

[DllImport("Crypt32.dll", SetLastError = true)]
private static extern bool CryptUnprotectData([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ByteArrayToDataBlobMarshaler))] byte[] pDataIn, [Optional] string ppszDataDescr, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ByteArrayToDataBlobMarshaler)), Optional] byte[] pOptionalEntropy, IntPtr pvReserved, [Optional] IntPtr pPromptStruct, int dwFlags, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ByteArrayToDataBlobMarshaler)), Out] byte[] pDataOut);

Marshaling into native code works fine, marshaling back seems to work too when using the debugger to step through the MarshalNativeToManaged method:
C#
public object MarshalNativeToManaged(IntPtr pNativeData)
{
    if (pNativeData == IntPtr.Zero) { return null; }
    int length = Marshal.ReadInt32(pNativeData);
    byte[] data = new byte[length];
    IntPtr dataPtr = Marshal.ReadIntPtr(pNativeData, IntPtr.Size);
    Marshal.Copy(dataPtr, data, 0, length);
    return data;
}

When arriving at the 'return data;' point, the array actually has the correct data in it.
The data is called from the following code:
C#
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
byte[] cipherBytes = new byte[0];
if (CryptProtectData(clearBytes, null, null, IntPtr.Zero, IntPtr.Zero, 0, cipherBytes))

After the call to this function, cipherBytes is still an empty array. According to standard C# rules this is to be expected, as i'm not sending cipherBytes as ref or out. So why do I actually expect it to be updated? Because the Marshal class can also do it.
I rewrote the code a little bit and used a class with StructLayout.Sequential and sent it to the native code, no matter how I send the parameters, Marshal completely ignores if it's an In, Out or InOut parameter and Always reads pDataIn, and always overwrites pDataOut, I expected the same from ICustomMarshaler.

The imports for sending it as a struct have errors in them, intentional, as I was trying to see how the In and Out attributes are used when marshaling as UnmanagedType.LPStruct. Turns out they're ignored.
C#
[DllImport("Crypt32.dll", SetLastError = true, EntryPoint = "CryptProtectData")]
private static extern bool CryptProtectData4([MarshalAs(UnmanagedType.LPStruct), Out] DataBlob pDataIn, [Optional] string szDataDescr, [MarshalAs(UnmanagedType.LPStruct), Optional] DataBlob pOptionalEntropy, IntPtr pvReserved, [Optional] IntPtr pPromptStruct, int dwFlags, [MarshalAs(UnmanagedType.LPStruct), Out] DataBlob pDataOut);
[DllImport("Crypt32.dll", SetLastError = true, EntryPoint = "CryptUnprotectData")]
private static extern bool CryptUnprotectData4([MarshalAs(UnmanagedType.LPStruct), Out] DataBlob pDataIn, [Optional] string ppszDataDescr, [MarshalAs(UnmanagedType.LPStruct), Optional] DataBlob pOptionalEntropy, IntPtr pvReserved, [Optional] IntPtr pPromptStruct, int dwFlags, [MarshalAs(UnmanagedType.LPStruct), Out] DataBlob pDataOut);

The class is actually longer, has a nice destructor for cleaning up the unmanaged memory and changing the data in the array, but trying to keep the snippets short.
C#
[StructLayout(LayoutKind.Sequential)]
internal class DataBlob
{
    [MarshalAs(UnmanagedType.U4)]
    private int Length;
    private IntPtr Data;
}

The code calling it:
C#
string clearText = "TestString";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
DataBlob clearBlob = new DataBlob(clearBytes);
DataBlob cipherBlob = new DataBlob();
CryptProtectData4(clearBlob, null, null, IntPtr.Zero, IntPtr.Zero, 0, cipherBlob);
byte[] cipherBytes = cipherBlob.GetData();

Even when sending pDataOut decorated with an In attribute, this code manages to change my private fields (not properties), so why can't my ICustomMarshaler change stuff?
AnswerRe: ICustomMarshaler not returning an Out parameter Pin
Luc Pattyn21-Jan-16 15:18
sitebuilderLuc Pattyn21-Jan-16 15:18 
GeneralRe: ICustomMarshaler not returning an Out parameter Pin
mavl21-Jan-16 23:08
mavl21-Jan-16 23:08 
GeneralRe: ICustomMarshaler not returning an Out parameter Pin
Luc Pattyn22-Jan-16 4:40
sitebuilderLuc Pattyn22-Jan-16 4:40 
GeneralRe: ICustomMarshaler not returning an Out parameter Pin
mavl22-Jan-16 8:58
mavl22-Jan-16 8:58 
GeneralRe: ICustomMarshaler not returning an Out parameter Pin
Luc Pattyn22-Jan-16 9:10
sitebuilderLuc Pattyn22-Jan-16 9:10 
GeneralRe: ICustomMarshaler not returning an Out parameter Pin
mavl22-Jan-16 23:15
mavl22-Jan-16 23:15 
GeneralRe: ICustomMarshaler not returning an Out parameter Pin
Luc Pattyn23-Jan-16 0:43
sitebuilderLuc Pattyn23-Jan-16 0:43 
GeneralRe: ICustomMarshaler not returning an Out parameter Pin
mavl23-Jan-16 2:49
mavl23-Jan-16 2:49 
AnswerRe: ICustomMarshaler not returning an Out parameter Pin
Gerry Schmitz21-Jan-16 16:03
mveGerry Schmitz21-Jan-16 16:03 
GeneralRe: ICustomMarshaler not returning an Out parameter Pin
mavl21-Jan-16 23:32
mavl21-Jan-16 23:32 
QuestionHow to redirect the weburl to particular country when user types in Browser. Pin
pradeep yajamanam21-Jan-16 1:52
pradeep yajamanam21-Jan-16 1:52 
AnswerRe: How to redirect the weburl to particular country when user types in Browser. Pin
Dave Kreskowiak21-Jan-16 4:54
mveDave Kreskowiak21-Jan-16 4:54 
AnswerRe: How to redirect the weburl to particular country when user types in Browser. Pin
Richard MacCutchan21-Jan-16 5:03
mveRichard MacCutchan21-Jan-16 5:03 
AnswerRe: How to redirect the weburl to particular country when user types in Browser. Pin
Gerry Schmitz21-Jan-16 8:34
mveGerry Schmitz21-Jan-16 8:34 
Questiongetting country from phone number Pin
Asrour20-Jan-16 10:46
Asrour20-Jan-16 10:46 
AnswerRe: getting country from phone number Pin
Richard Andrew x6420-Jan-16 11:32
professionalRichard Andrew x6420-Jan-16 11:32 
GeneralRe: getting country from phone number Pin
Asrour20-Jan-16 11:40
Asrour20-Jan-16 11:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.