Real quick question

I have a filter driver working and filtering IP packets.
These packets are depicted in instances of a struct, based on the IP filter example in the DDK and contain other stucts defined in ntddk.h

I want to return instances of these structs back to user mode app via buffered IO.

I can return simple structs back to user mode successfully, but wondered about thinks like linked lists (LIST_ENTRY) etc defined in ntddk.h

Can this be done? Is there an api in user mode to walk and manage the linked list?

Or am I in cloud cookoo land?

For into, this is the struct I want to return to user mode

typedef struct TL_INSPECT_PENDED_PACKET_  
{  
 LIST_ENTRY listEntry;  
  
ADDRESS_FAMILY addressFamily;  
 TL_INSPECT_PACKET_TYPE type;  
 FWP_DIRECTION direction;  
  
UINT32 authConnectDecision;  
 HANDLE completionContext;  
  
//  
 // Common fields for inbound and outbound traffic.  
 //  
 UINT8 protocol;  
 NET_BUFFER_LIST\* netBufferList;  
 COMPARTMENT_ID compartmentId;  
 union  
 {  
 FWP_BYTE_ARRAY16 localAddr;  
 UINT32 ipv4LocalAddr;  
 };  
 union  
 {  
 UINT16 localPort;  
 UINT16 icmpType;  
 };  
 union  
 {  
 UINT16 remotePort;  
 UINT16 icmpCode;  
 };  
  
//  
 // Data fields for outbound packet re-injection.  
 //  
 UINT64 endpointHandle;  
 union  
 {  
 FWP_BYTE_ARRAY16 remoteAddr;  
 UINT32 ipv4RemoteAddr;  
 };  
  
SCOPE_ID remoteScopeId;  
 WSACMSGHDR\* controlData;  
 ULONG controlDataLength;  
  
//  
 // Data fields for inbound packet re-injection.  
 //  
 BOOLEAN ipSecProtected;  
 ULONG nblOffset;  
 UINT32 ipHeaderSize;  
 UINT32 transportHeaderSize;  
 IF_INDEX interfaceIndex;  
 IF_INDEX subInterfaceIndex;  
} TL_INSPECT_PENDED_PACKET;  

Return a counted array of structs back to user mode. There’s plenty
of API calls that do something like this.

You will need to cope with telling the user how much buffer space is
required to return the data. Also, you might need to be able to
indicate that more data is present than transferred in the buffer and
consequently to be able to resume passing the data given an index
count in to the list.

At 21:18 31/10/2009, xxxxx@yahoo.co.uk wrote:

I have a filter driver working and filtering IP packets.
These packets are depicted in instances of a struct, based on the IP
filter example in the DDK and contain other stucts defined in ntddk.h

I want to return instances of these structs back to user mode app
via buffered IO.

I can return simple structs back to user mode successfully, but
wondered about thinks like linked lists (LIST_ENTRY) etc defined in ntddk.h

Can this be done? Is there an api in user mode to walk and manage
the linked list?

Or am I in cloud cookoo land?

For into, this is the struct I want to return to user mode

typedef struct TL_INSPECT_PENDED_PACKET_  
{  
LIST_ENTRY listEntry;  
 
ADDRESS_FAMILY addressFamily;  
TL_INSPECT_PACKET_TYPE type;  
FWP_DIRECTION direction;  
 
UINT32 authConnectDecision;  
HANDLE completionContext;  
 
//  
// Common fields for inbound and outbound traffic.  
//  
UINT8 protocol;  
NET_BUFFER_LIST\* netBufferList;  
COMPARTMENT_ID compartmentId;  
union  
{  
FWP_BYTE_ARRAY16 localAddr;  
UINT32 ipv4LocalAddr;  
};  
union  
{  
UINT16 localPort;  
UINT16 icmpType;  
};  
union  
{  
UINT16 remotePort;  
UINT16 icmpCode;  
};  
 
//  
// Data fields for outbound packet re-injection.  
//  
UINT64 endpointHandle;  
union  
{  
FWP_BYTE_ARRAY16 remoteAddr;  
UINT32 ipv4RemoteAddr;  
};  
 
SCOPE_ID remoteScopeId;  
WSACMSGHDR\* controlData;  
ULONG controlDataLength;  
 
//  
// Data fields for inbound packet re-injection.  
//  
BOOLEAN ipSecProtected;  
ULONG nblOffset;  
UINT32 ipHeaderSize;  
UINT32 transportHeaderSize;  
IF_INDEX interfaceIndex;  
IF_INDEX subInterfaceIndex;  
} TL_INSPECT_PENDED_PACKET;  

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

Err, ok??

If I declare that struct in user mode app, the first thing it does is complain it does not know what a LIST_ENTRY is. This is declared in ntddk.h

So I would have to add

#include “c:\winddk\blah\ntddk.h”

So I have now included ddk code in my user mode app. Is this ok? I thought it wasn’t ok.
Also there are kernel mode apis to walk the LIST_ENTRY, what are the user mode equivalents?

Err … you create a U/m include file for your struct.

There it might not include your LIST_ENTRY field, you just have to
cope with this in the K/M data copy routines.

Or, you can cut and paste the LIST_ENTRY definition in to the U/m include file.

Or create a dummy version of your own devising using PVOID.

Basic C programming.

At 21:37 31/10/2009, xxxxx@yahoo.co.uk wrote:

Err, ok??

If I declare that struct in user mode app, the first thing it does
is complain it does not know what a LIST_ENTRY is. This is declared in ntddk.h

So I would have to add

#include “c:\winddk\blah\ntddk.h”

So I have now included ddk code in my user mode app. Is this ok? I
thought it wasn’t ok.
Also there are kernel mode apis to walk the LIST_ENTRY, what are the
user mode equivalents?

Passing shared memory from K/M to U/M is basic C programming?

Shared memory is not basic C programming.

Passing a counted array of structs in a buffer is.

At 21:52 31/10/2009, xxxxx@yahoo.co.uk wrote:

Passing shared memory from K/M to U/M is basic C programming?


NTDEV is sponsored by OSR

>>Passing a counted array of structs in a buffer is.

Agreed.

PVOID is a good idea and will get me out of a hole.

Thanks for your help. :slight_smile:

If the data you are passing between UM and KM contains pointer sized data you need to be careful when you have 64bit os and 32bit user mode program and handle that case correctly.

Alex

Date: Sat, 31 Oct 2009 18:06:30 -0400
From: xxxxx@yahoo.co.uk
To: xxxxx@lists.osr.com
Subject: RE:[ntdev] Real quick question

>>Passing a counted array of structs in a buffer is.

Agreed.

PVOID is a good idea and will get me out of a hole.

Thanks for your help. :slight_smile:


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


Windows 7: Simplify your PC. Learn more.
http://www.microsoft.com/Windows/windows-7/default.aspx?ocid=PID24727::T:WLMTAGL:ON:WL:en-US:WWL_WIN_evergreen1:102009

I think it will be simpler if you have two struct defs, one in km as you posted and another for um that does not contain any pointers or other meaningless fields. When you get the ioctl for the data, you copy field by field or by memory ranges, translating from the km to um version of the struct.

d

Sent from my phone with no t9, all spilling mistakes are not intentional.

-----Original Message-----
From: xxxxx@yahoo.co.uk
Sent: Saturday, October 31, 2009 2:21 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Real quick question

I have a filter driver working and filtering IP packets.
These packets are depicted in instances of a struct, based on the IP filter example in the DDK and contain other stucts defined in ntddk.h

I want to return instances of these structs back to user mode app via buffered IO.

I can return simple structs back to user mode successfully, but wondered about thinks like linked lists (LIST_ENTRY) etc defined in ntddk.h

Can this be done? Is there an api in user mode to walk and manage the linked list?

Or am I in cloud cookoo land?

For into, this is the struct I want to return to user mode

<br>typedef struct TL_INSPECT_PENDED_PACKET_<br>{<br> LIST_ENTRY listEntry;<br><br>ADDRESS_FAMILY addressFamily;<br> TL_INSPECT_PACKET_TYPE type;<br> FWP_DIRECTION direction;<br><br>UINT32 authConnectDecision;<br> HANDLE completionContext;<br><br>//<br> // Common fields for inbound and outbound traffic.<br> //<br> UINT8 protocol;<br> NET_BUFFER_LIST* netBufferList;<br> COMPARTMENT_ID compartmentId;<br> union<br> {<br> FWP_BYTE_ARRAY16 localAddr;<br> UINT32 ipv4LocalAddr;<br> };<br> union<br> {<br> UINT16 localPort;<br> UINT16 icmpType;<br> };<br> union<br> {<br> UINT16 remotePort;<br> UINT16 icmpCode;<br> };<br><br>//<br> // Data fields for outbound packet re-injection.<br> //<br> UINT64 endpointHandle;<br> union<br> {<br> FWP_BYTE_ARRAY16 remoteAddr;<br> UINT32 ipv4RemoteAddr;<br> };<br><br>SCOPE_ID remoteScopeId;<br> WSACMSGHDR* controlData;<br> ULONG controlDataLength;<br><br>//<br> // Data fields for inbound packet re-injection.<br> //<br> BOOLEAN ipSecProtected;<br> ULONG nblOffset;<br> UINT32 ipHeaderSize;<br> UINT32 transportHeaderSize;<br> IF_INDEX interfaceIndex;<br> IF_INDEX subInterfaceIndex;<br>} TL_INSPECT_PENDED_PACKET;<br>


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

xxxxx@yahoo.co.uk wrote:

If I declare that struct in user mode app, the first thing it does is complain it does not know what a LIST_ENTRY is. This is declared in ntddk.h

So I would have to add

#include “c:\winddk\blah\ntddk.h”

So I have now included ddk code in my user mode app. Is this ok? I thought it wasn’t ok.
Also there are kernel mode apis to walk the LIST_ENTRY, what are the user mode equivalents?

The LIST_ENTRY section of the DDK stands alone. You can pop into wdm.h
and cut-and-paste the whole section into a user-mode include file. All
of the non-interlocked APIs are implemented as macros, so you don’t even
need a library.


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

I think that these may be duplicated in a Usermode header - I wish I could
remember which :slight_smile:

Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, November 02, 2009 12:38 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Real quick question

xxxxx@yahoo.co.uk wrote:

If I declare that struct in user mode app, the first thing it does is
complain it does not know what a LIST_ENTRY is. This is declared in ntddk.h

So I would have to add

#include “c:\winddk\blah\ntddk.h”

So I have now included ddk code in my user mode app. Is this ok? I thought
it wasn’t ok.
Also there are kernel mode apis to walk the LIST_ENTRY, what are the user
mode equivalents?

The LIST_ENTRY section of the DDK stands alone. You can pop into wdm.h
and cut-and-paste the whole section into a user-mode include file. All
of the non-interlocked APIs are implemented as macros, so you don’t even
need a library.


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

David R. Cattley wrote:

I think that these may be duplicated in a Usermode header - I wish I could
remember which :slight_smile:

The structs are defined in winnt.h. The APIs and macros are not present
in the SDK.


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

Ok, so you shamed me into looking first before I respond :wink:

winnt.h and ntdef.h both have definitions. winnt.h is indeed in the
Platform SDK as well as the inc\api headers of the WDK.

Cheers,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, November 02, 2009 1:37 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Real quick question

David R. Cattley wrote:

I think that these may be duplicated in a Usermode header - I wish I could
remember which :slight_smile:

The structs are defined in winnt.h. The APIs and macros are not present
in the SDK.


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

It is interesting to note that including a structure as simple as LIST_ENTRY
into a structure shared between user-mode and kernel-mode introduces
unanticipated problems.

Since LIST_ENTRY consists of two pointers the size will depend on whether
the structure is compiled for 32 or 64 bits. So, if the application
allocating the structure is 32 bits and the driver is 64 bits there will
misinterpretation of data and possibly a crash.

One solution to work around this is to put the LIST_ENTRY field in an
unnamed union shared with two POINTER_64 fields:

union {
LIST_ENTRY qLink;
POINTER_64 Reserved;
};

Now there is always space for qLink regardless of bitness.

Thomas F. Divine


From: “David R. Cattley”
Sent: Monday, November 02, 2009 2:16 PM
To: “Windows System Software Devs Interest List”
Subject: RE: [ntdev] Real quick question

> Ok, so you shamed me into looking first before I respond :wink:
>
> winnt.h and ntdef.h both have definitions. winnt.h is indeed in the
> Platform SDK as well as the inc\api headers of the WDK.
>
> Cheers,
> Dave Cattley
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
> Sent: Monday, November 02, 2009 1:37 PM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] Real quick question
>
> David R. Cattley wrote:
>> I think that these may be duplicated in a Usermode header - I wish I
>> could
>> remember which :slight_smile:
>>
>
> The structs are defined in winnt.h. The APIs and macros are not present
> in the SDK.
>
> –
> 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

I screwed up. Need space for two 64-bit pointers…

union {
LIST_ENTRY qLink;
POINTER_64 Reserved[2]; <= My Mistake…
};

Thomas


From: “David R. Cattley”
Sent: Monday, November 02, 2009 2:16 PM
To: “Windows System Software Devs Interest List”
Subject: RE: [ntdev] Real quick question

> Ok, so you shamed me into looking first before I respond :wink:
>
> winnt.h and ntdef.h both have definitions. winnt.h is indeed in the
> Platform SDK as well as the inc\api headers of the WDK.
>
> Cheers,
> Dave Cattley
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
> Sent: Monday, November 02, 2009 1:37 PM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] Real quick question
>
> David R. Cattley wrote:
>> I think that these may be duplicated in a Usermode header - I wish I
>> could
>> remember which :slight_smile:
>>
>
> The structs are defined in winnt.h. The APIs and macros are not present
> in the SDK.
>
> –
> 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

Thomas F. Divine wrote:

I screwed up. Need space for two 64-bit pointers…

union {
LIST_ENTRY qLink;
POINTER_64 Reserved[2]; <= My Mistake…
};

The user-mode version in winnt.h also defines LIST_ENTRY32 and
LIST_ENTRY64 for explicitly stating the intent, but I’m not sure any of
this really helps in the cross-culture scenario you previously mentioned.

The pitfalls and corner cases involved in passing user-mode pointers
directly to kernel mode are bad enough to begin with that this probably
becomes a relatively small part of the problem as a whole…


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

Actually, the OP doesn’t need to be concerned about this if the
kernel structures are re-organised sensibly.

Ignoring the setup and validation something along these lines will work:

typedef struct
{
ULONG Field1;
ULONG Field2:
. . .
} COMMON_STRUCT;

typedef struct
{
LIST_ENTRY ListEntry;

COMMON_STRUCT UserData;
} LIST_STRUCT;

Then in the relevant ioctl handler the OP walks the list and copies
just the COMMON_STRUCT in the user buffer.

No need to worry about 32/64 bit issues.

{
COMMON_STRUCT * pUserBuffer;
LIST_STRUCT * pListStruct;

//
// Request & Buffer validation ommitted.

pUserBuffer = (COMMON_STRUCT *) pIrp->AssociatedIrp.SystemBuffer;
while (ListItem)
{
[pListStruct = currentItem]

RtlCopyMemory (pUserBuffer,
&pListEntry->UserData,
sizeof (COMMON_STRUCT));
pUserBuffer ++;

// Check for running off end of user buffer.
}
}

Mark.

At 20:28 02/11/2009, Tim Roberts wrote:

Thomas F. Divine wrote:
> I screwed up. Need space for two 64-bit pointers…
>
> union {
> LIST_ENTRY qLink;
> POINTER_64 Reserved[2]; <= My Mistake…
> };

The user-mode version in winnt.h also defines LIST_ENTRY32 and
LIST_ENTRY64 for explicitly stating the intent, but I’m not sure any of
this really helps in the cross-culture scenario you previously mentioned.

The pitfalls and corner cases involved in passing user-mode pointers
directly to kernel mode are bad enough to begin with that this probably
becomes a relatively small part of the problem as a whole…


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

Actually the OP is a little out of his depth here and is really struggling. The option of creating a simplified structure for user mode is a good one, but sadly I need to keep the structures as identical as possible as I am going to pass the structure back to the driver in some instances.

I have declared a user mode equivalent using PVOIDS, but now the data is totally garbled. ???

typedef enum TL_INSPECT_PACKET_TYPE_  
{  
 TL_INSPECT_CONNECT_PACKET,  
 TL_INSPECT_DATA_PACKET,  
 TL_INSPECT_REAUTH_PACKET  
} TL_INSPECT_PACKET_TYPE;  
  
typedef enum FWP_DIRECTION_ {   
 FWP_DIRECTION_OUTBOUND = 0,   
 FWP_DIRECTION_INBOUND,   
 FWP_DIRECTION_MAX  
 } FWP_DIRECTION;  
  
typedef enum {   
 UNSPECIFIED_COMPARTMENT_ID = 0,   
 DEFAULT_COMPARTMENT_ID  
 } COMPARTMENT_ID, \*PCOMPARTMENT_ID;  
  
typedef struct FWP_BYTE_ARRAY16_   
{   
 UINT8 byteArray16[16];  
} FWP_BYTE_ARRAY16;  
  
typedef struct {  
 union {  
 struct {  
 ULONG Zone : 28;  
 ULONG Level : 4;  
 };  
 ULONG Value;  
 };  
} SCOPE_ID, \*PSCOPE_ID;  
  
typedef struct TL_INSPECT_PENDED_PACKET_  
{  
 LIST_ENTRY listEntry;  
  
ADDRESS_FAMILY addressFamily;  
 TL_INSPECT_PACKET_TYPE type;  
 FWP_DIRECTION direction;  
  
UINT32 authConnectDecision;  
 HANDLE completionContext;  
  
//  
 // Common fields for inbound and outbound traffic.  
 //  
 UINT8 protocol;  
 PVOID netBufferList;  
 COMPARTMENT_ID compartmentId;  
 union  
 {  
 FWP_BYTE_ARRAY16 localAddr;  
 UINT32 ipv4LocalAddr;  
 };  
 union  
 {  
 UINT16 localPort;  
 UINT16 icmpType;  
 };  
 union  
 {  
 UINT16 remotePort;  
 UINT16 icmpCode;  
 };  
  
//  
 // Data fields for outbound packet re-injection.  
 //  
 UINT64 endpointHandle;  
 union  
 {  
 FWP_BYTE_ARRAY16 remoteAddr;  
 UINT32 ipv4RemoteAddr;  
 };  
  
SCOPE_ID remoteScopeId;  
 PVOID controlData;  
 ULONG controlDataLength;  
  
//  
 // Data fields for inbound packet re-injection.  
 //  
 BOOLEAN ipSecProtected;  
 ULONG nblOffset;  
 UINT32 ipHeaderSize;  
 UINT32 transportHeaderSize;  
 IF_INDEX interfaceIndex;  
 IF_INDEX subInterfaceIndex;  
} TL_INSPECT_PENDED_PACKET;  
  

It is fine as far as the protocol member, so I think the problem is around the NET_BUFFER_LIST, which in KM is declared as

NET_BUFFER_LIST*

so in UM I can declare as PVOID?

:frowning:

You must provide simplified data (flat array of bytes) in the data you pass
up to user mode. There is no practical way around this chore.

You can queue the NB in the driver until you get disposition guidance back
from user mode.

To correlate the NB representation (known only to the driver) and the flat
array (passed to user mode) the driver can assign a reference number that is
incremented by the driver. Pass the reference number to user mode along with
the flat representation of each packet. The user mode guidance back to the
driver would include the packet reference number and the enum specifying
what to do with the original packet that is in a driver queue somewhere.

I suspect that you’ll balk at this sort of suggestion and keep along the
path you think should work. Eventually you’ll come around…

Thomas


From:
Sent: Monday, November 02, 2009 4:23 PM
To: “Windows System Software Devs Interest List”
Subject: RE:[ntdev] Real quick question

> Actually the OP is a little out of his depth here and is really
> struggling. The option of creating a simplified structure for user mode is
> a good one, but sadly I need to keep the structures as identical as
> possible as I am going to pass the structure back to the driver in some
> instances.
>
> I have declared a user mode equivalent using PVOIDS, but now the data is
> totally garbled. ???
>
> <br>&gt; typedef enum TL_INSPECT_PACKET_TYPE_<br>&gt; {<br>&gt; TL_INSPECT_CONNECT_PACKET,<br>&gt; TL_INSPECT_DATA_PACKET,<br>&gt; TL_INSPECT_REAUTH_PACKET<br>&gt; } TL_INSPECT_PACKET_TYPE;<br>&gt;<br>&gt; typedef enum FWP_DIRECTION_ {<br>&gt; FWP_DIRECTION_OUTBOUND = 0,<br>&gt; FWP_DIRECTION_INBOUND,<br>&gt; FWP_DIRECTION_MAX<br>&gt; } FWP_DIRECTION;<br>&gt;<br>&gt; typedef enum {<br>&gt; UNSPECIFIED_COMPARTMENT_ID = 0,<br>&gt; DEFAULT_COMPARTMENT_ID<br>&gt; } COMPARTMENT_ID, *PCOMPARTMENT_ID;<br>&gt;<br>&gt; typedef struct FWP_BYTE_ARRAY16_<br>&gt; {<br>&gt; UINT8 byteArray16[16];<br>&gt; } FWP_BYTE_ARRAY16;<br>&gt;<br>&gt; typedef struct {<br>&gt; union {<br>&gt; struct {<br>&gt; ULONG Zone : 28;<br>&gt; ULONG Level : 4;<br>&gt; };<br>&gt; ULONG Value;<br>&gt; };<br>&gt; } SCOPE_ID, *PSCOPE_ID;<br>&gt;<br>&gt; typedef struct TL_INSPECT_PENDED_PACKET_<br>&gt; {<br>&gt; LIST_ENTRY listEntry;<br>&gt;<br>&gt; ADDRESS_FAMILY addressFamily;<br>&gt; TL_INSPECT_PACKET_TYPE type;<br>&gt; FWP_DIRECTION direction;<br>&gt;<br>&gt; UINT32 authConnectDecision;<br>&gt; HANDLE completionContext;<br>&gt;<br>&gt; //<br>&gt; // Common fields for inbound and outbound traffic.<br>&gt; //<br>&gt; UINT8 protocol;<br>&gt; PVOID netBufferList;<br>&gt; COMPARTMENT_ID compartmentId;<br>&gt; union<br>&gt; {<br>&gt; FWP_BYTE_ARRAY16 localAddr;<br>&gt; UINT32 ipv4LocalAddr;<br>&gt; };<br>&gt; union<br>&gt; {<br>&gt; UINT16 localPort;<br>&gt; UINT16 icmpType;<br>&gt; };<br>&gt; union<br>&gt; {<br>&gt; UINT16 remotePort;<br>&gt; UINT16 icmpCode;<br>&gt; };<br>&gt;<br>&gt; //<br>&gt; // Data fields for outbound packet re-injection.<br>&gt; //<br>&gt; UINT64 endpointHandle;<br>&gt; union<br>&gt; {<br>&gt; FWP_BYTE_ARRAY16 remoteAddr;<br>&gt; UINT32 ipv4RemoteAddr;<br>&gt; };<br>&gt;<br>&gt; SCOPE_ID remoteScopeId;<br>&gt; PVOID controlData;<br>&gt; ULONG controlDataLength;<br>&gt;<br>&gt; //<br>&gt; // Data fields for inbound packet re-injection.<br>&gt; //<br>&gt; BOOLEAN ipSecProtected;<br>&gt; ULONG nblOffset;<br>&gt; UINT32 ipHeaderSize;<br>&gt; UINT32 transportHeaderSize;<br>&gt; IF_INDEX interfaceIndex;<br>&gt; IF_INDEX subInterfaceIndex;<br>&gt; } TL_INSPECT_PENDED_PACKET;<br>&gt;<br>&gt;
>
> It is fine as far as the protocol member, so I think the problem is around
> the NET_BUFFER_LIST, which in KM is declared as
>
> NET_BUFFER_LIST*
>
> so in UM I can declare as PVOID?
>
> :frowning:
>
> —
> 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

No, that sounds reasonable to me. No need to keep flogging a dead horse when someone makes a better suggestion. :slight_smile:

I think I was lulled into a false sense of security by this PVOID malarky. If it sounds to good to be true …

So for interest am I completely wrong in my understanding that a KM structure

NET_BUFFER_LIST*

cannot be represented in UM as

PVOID

as it totally stuffs the byte alignment and garbles my data?