c# and FilterGetMessage (IFSD)

Hello Members,
I am new to this list, please help me i have a problem doing a native call to kernel mode driver from c#.
I want to connect to a kernel mode file system filter driver via c#.

First I wrote in native c++ and everyting worked fine, this was just for testing issue during the driver development, because the user mode application should run under .NET so I switched to
c#

The call of FilterConnectCommunicationPort works fine from c# with the follwing code:

[DllImport(“fltlib”, SetLastError = true)]
public static extern int FilterConnectCommunicationPort([MarshalAs(UnmanagedType.LPWStr)]
string portName,
uint options,
IntPtr context,
uint sizeOfContext,
IntPtr securityAttributes,
IntPtr portPtr);

IntPtr portPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));

string portName = “\FilterPort”;
int status = FilterConnectCommunicationPort(
portName,
0,
IntPtr.Zero,
0,
IntPtr.Zero,
portPtr);

As I could watch in the debug output of the driver the connectNotfiyCallback Routine is called and the status
on the client side is 0 which means, that the operation was successful.

so everything was fine until here, but

when I call FilterGetMessage from the clientside it results in a status of 80070006 by the following code:

[DllImport(“fltlib”, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
public static extern unsafe uint FilterGetMessage(
SafeFileHandle hPort,
IntPtr messageBuffer,
int msgSize,
IntPtr Overlapped);

IntPtr message = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
SafeFileHandle sf = new SafeFileHandle(portPtr, true);

status = FilterGetMessage(
sf,
message,
Marshal.SizeOf(typeof(IntPtr)),
IntPtr.Zero);

So I guess, that there is anything wrong with the Arguments in FilterGetMessage.
I tried also to define structs for the message because in the native world, the message Argument must be
a type of FILTER_MESSAGE_HEADER like this but it did not work either:

[StructLayout(LayoutKind.Explicit)]
public struct FILTER_MESSAGE_HEADER
{
[FieldOffset(0)]
public UInt32 ReplyLength;

[FieldOffset(4)]
public UInt64 MessageId;
}

[StructLayout(LayoutKind.Explicit)]
public struct RBAC_SYSTEM_MESSAGE
{
[FieldOffset(0)]
public UInt32 BytesToScan;

[FieldOffset(4)]
public UInt32 Reserved;

[FieldOffset(8)]
public char Contents;
}

[StructLayout(LayoutKind.Explicit)]
public struct RBAC_MESSAGE
{
[FieldOffset(0)]
public FILTER_MESSAGE_HEADER MessageHeader;

[FieldOffset(12)]
public RBAC_SYSTEM_MESSAGE MessageContent;
}

RBAC_MESSAGE message = new RBAC_MESSAGE();
message.MessageContent = new RBAC_SYSTEM_MESSAGE();
message.MessageHeader = new FILTER_MESSAGE_HEADER();

SafeFileHandle sf = new SafeFileHandle(portPtr, true);

status = NativeConnector.FilterGetMessage(
sf,
ref message.MessageHeader,
(uint)Marshal.SizeOf(message),
IntPtr.Zero);

Please could anyone help me sending example code for receiving messages and replying messages to kernel mode with c# or giving me a hint, thank you,
elias

Jetzt kostenlos herunterladen: Internet Explorer 8 und Mozilla Firefox 3.5 -
sicherer, schneller und einfacher! http://portal.gmx.net/de/go/chbrowser

I would write an intermediate native DLL and then call it from C#.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Hello Members,
> I am new to this list, please help me i have a problem doing a native call to kernel mode driver from c#.
> I want to connect to a kernel mode file system filter driver via c#.
>
> First I wrote in native c++ and everyting worked fine, this was just for testing issue during the driver development, because the user mode application should run under .NET so I switched to
> c#
>
> The call of FilterConnectCommunicationPort works fine from c# with the follwing code:
>
> [DllImport(“fltlib”, SetLastError = true)]
> public static extern int FilterConnectCommunicationPort([MarshalAs(UnmanagedType.LPWStr)]
> string portName,
> uint options,
> IntPtr context,
> uint sizeOfContext,
> IntPtr securityAttributes,
> IntPtr portPtr);
>
>
> IntPtr portPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
>
> string portName = “\FilterPort”;
> int status = FilterConnectCommunicationPort(
> portName,
> 0,
> IntPtr.Zero,
> 0,
> IntPtr.Zero,
> portPtr);
>
> As I could watch in the debug output of the driver the connectNotfiyCallback Routine is called and the status
> on the client side is 0 which means, that the operation was successful.
>
> so everything was fine until here, but
>
> when I call FilterGetMessage from the clientside it results in a status of 80070006 by the following code:
>
> [DllImport(“fltlib”, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
> public static extern unsafe uint FilterGetMessage(
> SafeFileHandle hPort,
> IntPtr messageBuffer,
> int msgSize,
> IntPtr Overlapped);
>
> IntPtr message = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
> SafeFileHandle sf = new SafeFileHandle(portPtr, true);
>
> status = FilterGetMessage(
> sf,
> message,
> Marshal.SizeOf(typeof(IntPtr)),
> IntPtr.Zero);
>
> So I guess, that there is anything wrong with the Arguments in FilterGetMessage.
> I tried also to define structs for the message because in the native world, the message Argument must be
> a type of FILTER_MESSAGE_HEADER like this but it did not work either:
>
>
> [StructLayout(LayoutKind.Explicit)]
> public struct FILTER_MESSAGE_HEADER
> {
> [FieldOffset(0)]
> public UInt32 ReplyLength;
>
> [FieldOffset(4)]
> public UInt64 MessageId;
> }
>
> [StructLayout(LayoutKind.Explicit)]
> public struct RBAC_SYSTEM_MESSAGE
> {
> [FieldOffset(0)]
> public UInt32 BytesToScan;
>
> [FieldOffset(4)]
> public UInt32 Reserved;
>
> [FieldOffset(8)]
> public char Contents;
> }
>
> [StructLayout(LayoutKind.Explicit)]
> public struct RBAC_MESSAGE
> {
> [FieldOffset(0)]
> public FILTER_MESSAGE_HEADER MessageHeader;
>
> [FieldOffset(12)]
> public RBAC_SYSTEM_MESSAGE MessageContent;
> }
>
>
> RBAC_MESSAGE message = new RBAC_MESSAGE();
> message.MessageContent = new RBAC_SYSTEM_MESSAGE();
> message.MessageHeader = new FILTER_MESSAGE_HEADER();
>
> SafeFileHandle sf = new SafeFileHandle(portPtr, true);
>
> status = NativeConnector.FilterGetMessage(
> sf,
> ref message.MessageHeader,
> (uint)Marshal.SizeOf(message),
> IntPtr.Zero);
>
> Please could anyone help me sending example code for receiving messages and replying messages to kernel mode with c# or giving me a hint, thank you,
> elias
> –
> Jetzt kostenlos herunterladen: Internet Explorer 8 und Mozilla Firefox 3.5 -
> sicherer, schneller und einfacher! http://portal.gmx.net/de/go/chbrowser
>

How does the marshal know the length and character set of contents?

> [FieldOffset(8)]
> public char Contents;

Thomas F. Divine


From: “Maxim S. Shatskih”
Sent: Friday, February 05, 2010 7:46 AM
Newsgroups: ntdev
To: “Windows System Software Devs Interest List”
Subject: Re:[ntdev] c# and FilterGetMessage (IFSD)

> I would write an intermediate native DLL and then call it from C#.
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
> wrote in message news:xxxxx@ntdev…
>> Hello Members,
>> I am new to this list, please help me i have a problem doing a native
>> call to kernel mode driver from c#.
>> I want to connect to a kernel mode file system filter driver via c#.
>>
>> First I wrote in native c++ and everyting worked fine, this was just for
>> testing issue during the driver development, because the user mode
>> application should run under .NET so I switched to
>> c#
>>
>> The call of FilterConnectCommunicationPort works fine from c# with the
>> follwing code:
>>
>> [DllImport(“fltlib”, SetLastError = true)]
>> public static extern int
>> FilterConnectCommunicationPort([MarshalAs(UnmanagedType.LPWStr)]
>> string portName,
>> uint options,
>> IntPtr context,
>> uint sizeOfContext,
>> IntPtr securityAttributes,
>> IntPtr portPtr);
>>
>>
>> IntPtr portPtr =
>> Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
>>
>> string portName = “\FilterPort”;
>> int status = FilterConnectCommunicationPort(
>> portName,
>> 0,
>> IntPtr.Zero,
>> 0,
>> IntPtr.Zero,
>> portPtr);
>>
>> As I could watch in the debug output of the driver the
>> connectNotfiyCallback Routine is called and the status
>> on the client side is 0 which means, that the operation was successful.
>>
>> so everything was fine until here, but
>>
>> when I call FilterGetMessage from the clientside it results in a status
>> of 80070006 by the following code:
>>
>> [DllImport(“fltlib”, CallingConvention = CallingConvention.Winapi,
>> CharSet = CharSet.Auto, SetLastError = true)]
>> public static extern unsafe uint FilterGetMessage(
>> SafeFileHandle hPort,
>> IntPtr messageBuffer,
>> int msgSize,
>> IntPtr Overlapped);
>>
>> IntPtr message =
>> Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
>> SafeFileHandle sf = new SafeFileHandle(portPtr, true);
>>
>> status = FilterGetMessage(
>> sf,
>> message,
>> Marshal.SizeOf(typeof(IntPtr)),
>> IntPtr.Zero);
>>
>> So I guess, that there is anything wrong with the Arguments in
>> FilterGetMessage.
>> I tried also to define structs for the message because in the native
>> world, the message Argument must be
>> a type of FILTER_MESSAGE_HEADER like this but it did not work either:
>>
>>
>> [StructLayout(LayoutKind.Explicit)]
>> public struct FILTER_MESSAGE_HEADER
>> {
>> [FieldOffset(0)]
>> public UInt32 ReplyLength;
>>
>> [FieldOffset(4)]
>> public UInt64 MessageId;
>> }
>>
>> [StructLayout(LayoutKind.Explicit)]
>> public struct RBAC_SYSTEM_MESSAGE
>> {
>> [FieldOffset(0)]
>> public UInt32 BytesToScan;
>>
>> [FieldOffset(4)]
>> public UInt32 Reserved;
>>
>> [FieldOffset(8)]
>> public char Contents;
>> }
>>
>> [StructLayout(LayoutKind.Explicit)]
>> public struct RBAC_MESSAGE
>> {
>> [FieldOffset(0)]
>> public FILTER_MESSAGE_HEADER MessageHeader;
>>
>> [FieldOffset(12)]
>> public RBAC_SYSTEM_MESSAGE MessageContent;
>> }
>>
>>
>> RBAC_MESSAGE message = new RBAC_MESSAGE();
>> message.MessageContent = new RBAC_SYSTEM_MESSAGE();
>> message.MessageHeader = new FILTER_MESSAGE_HEADER();
>>
>> SafeFileHandle sf = new SafeFileHandle(portPtr, true);
>>
>> status = NativeConnector.FilterGetMessage(
>> sf,
>> ref message.MessageHeader,
>> (uint)Marshal.SizeOf(message),
>> IntPtr.Zero);
>>
>> Please could anyone help me sending example code for receiving messages
>> and replying messages to kernel mode with c# or giving me a hint, thank
>> you,
>> elias
>> –
>> Jetzt kostenlos herunterladen: Internet Explorer 8 und Mozilla Firefox
>> 3.5 -
>> sicherer, schneller und einfacher! http://portal.gmx.net/de/go/chbrowser
>>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Hi Elias,

your pinvoke signatures look pretty wrong or at least suspicious. Let me start:

FilterConnectCommunicationPort has no reason for SetLastError, since it returns a HRESULT not a Windows Error code, so this attribute has no effect on the function. Then the last parameter must hPort be passed as out or at least ref parameter sind the clr runtime should marshal the data back from the callee to the caller, so this is missing here. You also should mak the parameter with the [In][Out] attributes, so they are also missing! Why do you mark the function “unsafe”, there is also no need for, since all can be done without any problem in “safe” mannaged mode and you do not use any unsafe syntax here. The same for FilterGetMessage. Why are you using CallingConvention.Winapi, SetLastError and CharSet.Auto. The Library looks allover UNICODE, no internal SetLastError and do you expect it to run on Windows CE/Mobile??? You also could use NativeOverlapped for the last parameter (marked [Optional]). The FilterGetMessage FILTER_MESSAGE_HEADER must be passed as ref parameter and your FILTER_MESSAGE_HEADER signature is little wrong. You dont have a union struct here to set offsets to members, though it is the same size, but its is more reasonable. A simple Layoutkind.Sequential is good enough:

[StructLayout(LayoutKind.Sequential)]
public struct FILTER_MESSAGE_HEADER
{
public uint ReplyLength;
public ulong MessageId;
}

I am not sure what yiur RBAC_SYSTEM_MESSAGE looks like, but the char could possibly be a StringBuilder, a string with a fixed length (SizeConst), maybe it needs to be some MarshalAs() to a explicit datatype, i dont know, but simply passing it as a array with no size/width information wont work! The runtime will complain on that, at least at runtime! And do not forget to free allocated heap memory, since the runtime will not take care of the unmannaged memory allocations and you run into leaks. Since the HRESULT is not clear what exactly it means, there are some reason why this possibly fails on your system.

First check all your signatures, make sure you run the right pinvokes, then try again. This is morre a question for here: microsoft.public.dotnet.framework.interop. And you have to provide morfe information about the original signatures and what they look like (when you write there).

Hope this helps,…

Regards

Kerem

One more suggestion. If you are writing the driver and the C# application, then define information in a “C# friendly” way. Microsoft does this in some cases. Below is the ‘C’ representation of IF_COUNTED_STRING structure.

Following that is a C# representation that marshals easily - because the string is always returned in a fixed-size block of memory. In addition, the Length is also available for consistency checks.

Having just done a lot of marshalling for WLAN API and OID_DOT11_xyz structures I know you can do this from managed code - but it takes a fair amount of work. There are a lot of cases where marshalling is not as easy as IF_COUNTED_STRING.

#define IF_MAX_STRING_SIZE 256

typedef struct _IF_COUNTED_STRING_LH
{
USHORT Length;
WCHAR String[IF_MAX_STRING_SIZE + 1];
} IF_COUNTED_STRING_LH, *PIF_COUNTED_STRING_LH;

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
public struct IF_COUNTED_STRING_LH
{
///
/// Length of the string in bytes.
///
public UInt16 Length;

///
/// The counted string bytes.
///
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = (Constants.IF_MAX_STRING_SIZE + 1))]
public string String;
}

Thomas F. Divine
http://www.pcausa.com

@Thomas Divine

Indeed, Pinvoke can be very tricky but most of the things, at least 99% can be solved managed when using right signatures and appropriate memory layout!

Regards

Kerem

That is also the approach I took as well. It worked just fine. Wrap
the filter interface in C# friendly C interfaces and call those
instead.

Mark Roddy

On Fri, Feb 5, 2010 at 7:46 AM, Maxim S. Shatskih
wrote:
> ? ?I would write an intermediate native DLL and then call it from C#.
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
> wrote in message news:xxxxx@ntdev…
>> Hello Members,
>> I am new to this list, please help me i have a problem doing a native call to kernel mode driver from c#.
>> I want to connect to a kernel mode file system filter driver via c#.
>>
>> First I wrote in native c++ and everyting worked fine, this was just for testing issue during the driver development, because the user mode application should run under .NET so I switched to
>> c#
>>
>> The call of FilterConnectCommunicationPort works fine from c# with the follwing code:
>>
>> ? ? ? ?[DllImport(“fltlib”, SetLastError = true)]
>> ? ? ? ?public static extern int FilterConnectCommunicationPort([MarshalAs(UnmanagedType.LPWStr)]
>> ? ? ? ? ? ?string portName,
>> ? ? ? ? ? ?uint options,
>> ? ? ? ? ? ?IntPtr context,
>> ? ? ? ? ? ?uint sizeOfContext,
>> ? ? ? ? ? ?IntPtr securityAttributes,
>> ? ? ? ? ? ?IntPtr portPtr);
>>
>>
>> ? ? ? ? ? ?IntPtr portPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
>>
>> ? ? ? ? ? ?string portName = “\FilterPort”;
>> ? ? ? ? ? ?int status = FilterConnectCommunicationPort(
>> ? ? ? ? ? ? ? ?portName,
>> ? ? ? ? ? ? ? ?0,
>> ? ? ? ? ? ? ? ?IntPtr.Zero,
>> ? ? ? ? ? ? ? ?0,
>> ? ? ? ? ? ? ? ?IntPtr.Zero,
>> ? ? ? ? ? ? ? ?portPtr);
>>
>> As I could watch in the debug output of the driver the connectNotfiyCallback Routine is called and the status
>> on the client side is 0 which means, that the operation was successful.
>>
>> so everything was fine until here, but
>>
>> when I call FilterGetMessage from the clientside it results in a status of 80070006 by the following code:
>>
>> [DllImport(“fltlib”, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)]
>> ? ? ? ?public static extern unsafe uint FilterGetMessage(
>> ? ? ? ? ? ?SafeFileHandle hPort,
>> ? ? ? ? ? ?IntPtr messageBuffer,
>> ? ? ? ? ? ?int msgSize,
>> ? ? ? ? ? ?IntPtr Overlapped);
>>
>> ? ? ? ? ? ?IntPtr message = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
>> ? ? ? ? ? ?SafeFileHandle sf = new SafeFileHandle(portPtr, true);
>>
>> ? ? ? ? ? ?status = FilterGetMessage(
>> ? ? ? ? ? ? ? ?sf,
>> ? ? ? ? ? ? ? ?message,
>> ? ? ? ? ? ? ? ?Marshal.SizeOf(typeof(IntPtr)),
>> ? ? ? ? ? ? ? ?IntPtr.Zero);
>>
>> So I guess, that there is anything wrong with the Arguments in FilterGetMessage.
>> I tried also to define structs for the message because in the native world, the message Argument must be
>> a type of FILTER_MESSAGE_HEADER like this but it did not work either:
>>
>>
>> ? ? ? ?[StructLayout(LayoutKind.Explicit)]
>> ? ? ? ?public struct FILTER_MESSAGE_HEADER
>> ? ? ? ?{
>> ? ? ? ? ? ?[FieldOffset(0)]
>> ? ? ? ? ? ?public UInt32 ReplyLength;
>>
>> ? ? ? ? ? ?[FieldOffset(4)]
>> ? ? ? ? ? ?public UInt64 MessageId;
>> ? ? ? ?}
>>
>> ? ? ? ?[StructLayout(LayoutKind.Explicit)]
>> ? ? ? ?public struct RBAC_SYSTEM_MESSAGE
>> ? ? ? ?{
>> ? ? ? ? ? ?[FieldOffset(0)]
>> ? ? ? ? ? ?public UInt32 BytesToScan;
>>
>> ? ? ? ? ? ?[FieldOffset(4)]
>> ? ? ? ? ? ?public UInt32 Reserved;
>>
>> ? ? ? ? ? ?[FieldOffset(8)]
>> ? ? ? ? ? ?public char Contents;
>> ? ? ? ?}
>>
>> ? ? ? ?[StructLayout(LayoutKind.Explicit)]
>> ? ? ? ?public struct RBAC_MESSAGE
>> ? ? ? ?{
>> ? ? ? ? ? ?[FieldOffset(0)]
>> ? ? ? ? ? ?public FILTER_MESSAGE_HEADER MessageHeader;
>>
>> ? ? ? ? ? ?[FieldOffset(12)]
>> ? ? ? ? ? ?public RBAC_SYSTEM_MESSAGE MessageContent;
>> ? ? ? ?}
>>
>>
>> ? ? ? ? ? ?RBAC_MESSAGE message = new RBAC_MESSAGE();
>> ? ? ? ? ? ?message.MessageContent = new RBAC_SYSTEM_MESSAGE();
>> ? ? ? ? ? ?message.MessageHeader = new FILTER_MESSAGE_HEADER();
>>
>> ? ? ? ? ? ?SafeFileHandle sf = new SafeFileHandle(portPtr, true);
>>
>> ? ? ? ? ? ?status = NativeConnector.FilterGetMessage(
>> ? ? ? ? ? ? ? ?sf,
>> ? ? ? ? ? ? ? ?ref message.MessageHeader,
>> ? ? ? ? ? ? ? ?(uint)Marshal.SizeOf(message),
>> ? ? ? ? ? ? ? ?IntPtr.Zero);
>>
>> Please could anyone help me sending example code for receiving messages and replying messages to kernel mode with c# or giving me a hint, thank you,
>> elias
>> –
>> Jetzt kostenlos herunterladen: Internet Explorer 8 und Mozilla Firefox 3.5 -
>> sicherer, schneller und einfacher! http://portal.gmx.net/de/go/chbrowser
>>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

@Mark Roddy

Yes, for some functions i did the same, even more. I wrote a function that got a nice and clean self-made structure and call interface, pass it as reference or out then call the function, fill the structure return a true or false, maybe a error code to indicate the failure and made all very easy to use. Wrapped inside a single easy to call function and saved lots of time and pinvoke,…

Regards

Kerem

>And do not forget to free allocated heap memory, since the runtime will not take care of the >unmannaged memory allocations and you run into leaks.
Kerem,

Do you mean if I do any allocation in unsafe block, for example Object1 m_obj1 = new Object1();,
Garbage Collector doesn’t work?
I think it should work. Or am I wrong?

Igor Sharovar

xxxxx@hotmail.com wrote:

> And do not forget to free allocated heap memory, since the runtime will not take care of the >unmannaged memory allocations and you run into leaks.
>
Kerem,

Do you mean if I do any allocation in unsafe block, for example Object1 m_obj1 = new Object1();,
Garbage Collector doesn’t work?
I think it should work. Or am I wrong?

The garbage collector will still work, but that object will not be
garbage collected. To allocate an object on the garbage-collected heap,
you must use “gcnew” instead of “new”.

Unmanaged memory is never garbage collected.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Just to make sure I understand:

Case 1:

BOZO _bozo;
bozo = new BOZO();

Case 2:

BOZO _bozo;
unsafe { bozo = new BOZO(); }

Case 1: No leak.
Case 2: Leaks. Use gcnew instead of new.

Correct?

If so, I have a leak and have learned something.

Thomas


From: “Tim Roberts”
Sent: Friday, February 05, 2010 8:46 PM
To: “Windows System Software Devs Interest List”
Subject: Re: [ntdev] c# and FilterGetMessage (IFSD)

> xxxxx@hotmail.com wrote:
>>> And do not forget to free allocated heap memory, since the runtime will
>>> not take care of the >unmannaged memory allocations and you run into
>>> leaks.
>>>
>> Kerem,
>>
>> Do you mean if I do any allocation in unsafe block, for example Object1
>> m_obj1 = new Object1();,
>> Garbage Collector doesn’t work?
>> I think it should work. Or am I wrong?
>>
>
> The garbage collector will still work, but that object will not be
> garbage collected. To allocate an object on the garbage-collected heap,
> you must use “gcnew” instead of “new”.
>
> Unmanaged memory is never garbage collected.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

I don’t think that’s correct.

See answer at: http://social.msdn.microsoft.com/Forums/en/clr/thread/024199b9-d0bb-429d-93ca-0e225e3f7c60

“Unsafe” is not Unmanaged. If you call any unmanaged API’s that return pointers to allocated memory, you must free that memory later.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Thomas F. Divine
Sent: Friday, February 05, 2010 5:54 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] c# and FilterGetMessage (IFSD)

Just to make sure I understand:

Case 1:

BOZO _bozo;
bozo = new BOZO();

Case 2:

BOZO _bozo;
unsafe { bozo = new BOZO(); }

Case 1: No leak.
Case 2: Leaks. Use gcnew instead of new.

Correct?

If so, I have a leak and have learned something.

Thomas


From: “Tim Roberts”
Sent: Friday, February 05, 2010 8:46 PM
To: “Windows System Software Devs Interest List”
Subject: Re: [ntdev] c# and FilterGetMessage (IFSD)

> xxxxx@hotmail.com wrote:
>>> And do not forget to free allocated heap memory, since the runtime will
>>> not take care of the >unmannaged memory allocations and you run into
>>> leaks.
>>>
>> Kerem,
>>
>> Do you mean if I do any allocation in unsafe block, for example Object1
>> m_obj1 = new Object1();,
>> Garbage Collector doesn’t work?
>> I think it should work. Or am I wrong?
>>
>
> The garbage collector will still work, but that object will not be
> garbage collected. To allocate an object on the garbage-collected heap,
> you must use “gcnew” instead of “new”.
>
> Unmanaged memory is never garbage collected.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

That was always my assumption, so anything allocated by wrapper
functions and handed out has a co-function to free that allocation.

Mark Roddy

On Fri, Feb 5, 2010 at 9:07 PM, Daniel Strommen
wrote:
> I don’t think that’s correct.
>
> See answer at: http://social.msdn.microsoft.com/Forums/en/clr/thread/024199b9-d0bb-429d-93ca-0e225e3f7c60
>
> “Unsafe” is not Unmanaged. ?If you call any unmanaged API’s that return pointers to allocated memory, you must free that memory later.
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Thomas F. Divine
> Sent: Friday, February 05, 2010 5:54 PM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] c# and FilterGetMessage (IFSD)
>
> Just to make sure I understand:
>
> Case 1:
>
> BOZO _bozo;
> bozo = new BOZO();
>
> Case 2:
>
> BOZO _bozo;
> unsafe { bozo = new BOZO(); }
>
> Case 1: No leak.
> Case 2: Leaks. Use gcnew instead of new.
>
> Correct?
>
> If so, I have a leak and have learned something.
>
> Thomas
>
>
>
>
> --------------------------------------------------
> From: “Tim Roberts”
> Sent: Friday, February 05, 2010 8:46 PM
> To: “Windows System Software Devs Interest List”
> Subject: Re: [ntdev] c# and FilterGetMessage (IFSD)
>
>> xxxxx@hotmail.com wrote:
>>>> And do not forget to free allocated heap memory, since the runtime will
>>>> not take care of the >unmannaged memory allocations and you run into
>>>> leaks.
>>>>
>>> Kerem,
>>>
>>> Do you mean if I do any allocation in unsafe block, for example Object1
>>> m_obj1 = new Object1();,
>>> Garbage Collector doesn’t work?
>>> I think it should work. Or am I wrong?
>>>
>>
>> The garbage collector will still work, but that object will not be
>> garbage collected. ?To allocate an object on the garbage-collected heap,
>> you must use “gcnew” instead of “new”.
>>
>> Unmanaged memory is never garbage collected.
>>
>> –
>> Tim Roberts, xxxxx@probo.com
>> Providenza & Boekelheide, Inc.
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

I also have a problem related to this.
If I write a filter driver to get some information about the device, Can I
pass them (information I got through filter driver) to C# application?

Let’s say that we write a filter driver to get Vendor ID and Product ID of a
device.
And I have a application which compare user inputs with above values.

Is this possible?


Prageeth Madhushanka

@Prageeth Madhushanka

Is this possible?

Sure it is, why not!

Thomas F. Divine wrote:

Just to make sure I understand:

Case 1:

BOZO _bozo;
bozo = new BOZO();

Case 2:

BOZO _bozo;
unsafe { bozo = new BOZO(); }

Case 1: No leak.
Case 2: Leaks. Use gcnew instead of new.

Correct?

Nope. Both of those cases will leak. The “new” operator, even in
managed code, allocates from unmanaged memory. If you allocate with
“new”, you must free with “delete”. If you allocate with “gcnew”, the
object will be garbage-collected when the last reference is removed. If
BOZO is a managed type (a “ref class”), both of those should give a
compiler error.

Note that much of this changed between the old “MC++” in VS2003 and the
new “C++/CLI” in VS2005 and later.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

>Nope. Both of those cases will leak. The “new” operator, even in managed code, allocates from >unmanaged memory. If you allocate with “new”, you must free with “delete”. If you allocate with >“gcnew”, the object will be garbage-collected when the last reference is removed. If BOZO is a >managed type (a “ref class”), both of those should give a compiler error. Note that much of this >changed between the old “MC++” in VS2003 and the new “C++/CLI” in VS2005 and later.

Tim,

Could you give any reference for what you say? As Daniel said “unsafe” statement is not unmanaged code. I don’t know if GC deallocating memory in unsafe blocks but GC still manages memory in such blocks in general. It is why key word “fixed” used in unsafe block to keep memory away of GC.

Igor Sharovar

xxxxx@hotmail.com wrote:

> Nope. Both of those cases will leak. The “new” operator, even in managed code, allocates from >unmanaged memory. If you allocate with “new”, you must free with “delete”. If you allocate with >“gcnew”, the object will be garbage-collected when the last reference is removed. If BOZO is a >managed type (a “ref class”), both of those should give a compiler error. Note that much of this >changed between the old “MC++” in VS2003 and the new “C++/CLI” in VS2005 and later.
>

Tim,

Could you give any reference for what you say? As Daniel said “unsafe” statement is not unmanaged code. I don’t know if GC deallocating memory in unsafe blocks but GC still manages memory in such blocks in general. It is why key word “fixed” used in unsafe block to keep memory away of GC.

The whole “unsafe” thing is unrelated to this. The “new” operator
allocates memory off of the native heap, exactly like it does in an
unmanaged program. The “gcnew” operator allocates memory off of the
managed heap. The managed heap is reference-counted and garbage
collected. The unmanaged heap is not. It’s just that simple.

http://blogs.msdn.com/hsutter/archive/2003/12/05/53522.aspx


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

Are you talking about C++ or C#?
The reference which you provide is related to C++, where new is unmanaged by default . I could not find any reference to gcnew for C# in MSDN.

Igor Sharovar

xxxxx@hotmail.com wrote:

Are you talking about C++ or C#?
The reference which you provide is related to C++, where new is unmanaged by default . I could not find any reference to gcnew for C# in MSDN.

Yes, C++. I now begin to suspect that you and I have been having two
entirely different conversations. My apologies.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.