All:

I must admit that I am just plain terrible at the creation of macros (I hardly ever use them) so I was wondering if some of you who are rather skilled at it could save me some time by reviewing the vary basic macros that I have created for use in my WDM tut and then suggest the proper way to make them.

Thanks in advance as this greatly assist in the efforts.




;++
;
; PIO_STACK_LOCATION
; IoGetCurrentIrpStackLocation(
; IN PIRP Irp
; )
;
; Routine Description:
;
; This routine is invoked to return a pointer to the current stack location
; in an I/O Request Packet (IRP).
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet.
;
; Return Value:
;
; The function value is a pointer to the current stack location in the
; packet.
;
;--
;#define IoMarkIrpPending( Irp ) ( \
; IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED )
;
IoGetCurrentIrpStackLocation MACRO pIrp:REQ
mov edi, pIrp
mov esi, (_IRP PTR [edi]).CurrentStackLocation
ENDM

;++
;
; VOID
; IoSkipCurrentIrpStackLocation (
; IN PIRP Irp
; )
;
; Routine Description:
;
; This routine is invoked to increment the current stack location of
; a given IRP.
;
; If the caller wishes to call the next driver in a stack, and does not
; wish to change the arguments, nor does he wish to set a completion
; routine, then the caller first calls IoSkipCurrentIrpStackLocation
; and the calls IoCallDriver.
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet.
;
; Return Value:
;
; None
;
;--
;#define IoSkipCurrentIrpStackLocation( Irp ) \
; (Irp)->CurrentLocation++; \
; (Irp)->Tail.Overlay.CurrentStackLocation++;
;
IoSkipCurrentIrpStackLocation MACRO pIrp:REQ
mov eax, pIrp
inc (_IRP PTR [eax]).CurrentLocation
inc (_IRP PTR [eax]).CurrentStackLocation
ENDM

;++
;
; PIO_STACK_LOCATION
; IoGetNextIrpStackLocation(
; IN PIRP Irp
; )
;
; Routine Description:
;
; This routine is invoked to return a pointer to the next stack location
; in an I/O Request Packet (IRP).
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet.
;
; Return Value:
;
; The function value is a pointer to the next stack location in the packet.
;
;--
;#define IoGetNextIrpStackLocation( Irp ) (\
; (Irp)->Tail.Overlay.CurrentStackLocation - 1 )
;
IoGetNextIrpStackLocation MACRO pIrp:REQ
mov edi, pIrp
mov esi, (_IRP PTR [edi]).CurrentStackLocation - 1
ENDM

;++
;
; VOID
; IoCopyCurrentIrpStackLocationToNext(
; IN PIRP Irp
; )
;
; Routine Description:
;
; This routine is invoked to copy the IRP stack arguments and file
; pointer from the current IrpStackLocation to the next
; in an I/O Request Packet (IRP).
;
; If the caller wants to call IoCallDriver with a completion routine
; but does not wish to change the arguments otherwise,
; the caller first calls IoCopyCurrentIrpStackLocationToNext,
; then IoSetCompletionRoutine, then IoCallDriver.
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet.
;
; Return Value:
;
; None.
;
;--
;
;#define IoCopyCurrentIrpStackLocationToNext( Irp ) { \
; PIO_STACK_LOCATION irpSp; \
; PIO_STACK_LOCATION nextIrpSp; \
; irpSp = IoGetCurrentIrpStackLocation( (Irp) ); \
; nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); \
; RtlCopyMemory( nextIrpSp, irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \
; nextIrpSp->Control = 0; }
;
IoCopyCurrentIrpStackLocationToNext MACRO pIrp:REQ
LOCAL irpSp
LOCAL nextIrpSp

irpSp DWORD ?
nextIrpSp DWORD ?

IoGetCurrentIrpStackLocation pIrp
mov irpSp, esi

IoGetNextIrpStackLocation pIrp
mov nextIrpSp, esi


;
; Get the needed Field offset and place it into eax
;
FIELD_OFFSET IO_STACK_LOCATION, \
CompletionRoutine

invoke RtlCopyMemory, nextIrpSp, \
irpSp, \
eax

mov (IO_STACK_LOCATION PTR [nextIrpSp]).Control, 0
ENDM

;++
;
; VOID
; IoSetCompletionRoutine(
; IN PIRP Irp,
; IN PIO_COMPLETION_ROUTINE CompletionRoutine,
; IN PVOID Context,
; IN BOOLEAN InvokeOnSuccess,
; IN BOOLEAN InvokeOnError,
; IN BOOLEAN InvokeOnCancel
; )
;
; Routine Description:
;
; This routine is invoked to set the address of a completion routine which
; is to be invoked when an I/O packet has been completed by a lower-level
; driver.
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet itself.
;
; CompletionRoutine - Address of the completion routine that is to be
; invoked once the next level driver completes the packet.
;
; Context - Specifies a context parameter to be passed to the completion
; routine.
;
; InvokeOnSuccess - Specifies that the completion routine is invoked when the
; operation is successfully completed.
;
; InvokeOnError - Specifies that the completion routine is invoked when the
; operation completes with an error status.
;
; InvokeOnCancel - Specifies that the completion routine is invoked when the
; operation is being canceled.
;
; Return Value:
;
; None.
;
;--
;
;#define IoSetCompletionRoutine( Irp, Routine, CompletionContext, Success, Error, Cancel ) { \
; PIO_STACK_LOCATION irpSp; \
; ASSERT( (Success) | (Error) | (Cancel) ? (Routine) != NULL : TRUE ); \
; irpSp = IoGetNextIrpStackLocation( (Irp) ); \
; irpSp->CompletionRoutine = (Routine); \
; irpSp->Context = (CompletionContext); \
; irpSp->Control = 0; \
; if ((Success)) { irpSp->Control = SL_INVOKE_ON_SUCCESS; } \
; if ((Error)) { irpSp->Control |= SL_INVOKE_ON_ERROR; } \
; if ((Cancel)) { irpSp->Control |= SL_INVOKE_ON_CANCEL; } }

IoSetCompletionRoutine MACRO pIrp:REQ, Routine:REQ, \
CompletionContext:REQ, \
Success:REQ, Error:REQ, \
Cancel:REQ

LOCAL irpSp

irpSp DWORD ?

IoGetNextIrpStackLocation pIrp

mov irpSp, esi
mov (IO_STACK_LOCATION PTR [irpSp]).CompletionRoutine, Routine

mov eax, DWORD PTR CompletionContext

mov (IO_STACK_LOCATION PTR [irpSp]).Context, eax
mov (IO_STACK_LOCATION PTR [irpSp]).Control, 0

.IF Success
mov (IO_STACK_LOCATION PTR [irpSp]).Control, SL_INVOKE_ON_SUCCESS
.ENDIF

.IF Error
or (IO_STACK_LOCATION PTR [irpSp]).Control, SL_INVOKE_ON_ERROR
.ENDIF

.IF Cancel
or (IO_STACK_LOCATION PTR [irpSp]).Control, SL_INVOKE_ON_CANCEL
.ENDIF

ENDM

;
; Calculate the byte offset of a field in a structure of type type.
;
;#define FIELD_OFFSET(type, field) ((LONG)(LONG_PTR)&(((type *)0)->field))
FIELD_OFFSET MACRO type:REQ, field:REQ
mov eax, type
mov eax, (type PTR [edx]).field
ENDM

Posted on 2003-01-08 17:21:20 by madprgmr
;

; Calculate the byte offset of a field in a structure of type type.
;
;#define FIELD_OFFSET(type, field) ((LONG)(LONG_PTR)&(((type *)0)->field))
FIELD_OFFSET MACRO _type:REQ, field:REQ
EXITM %(_type&.&field)
ENDM

; Example:
mov eax, FIELD_OFFSET(D3DXCOLOR, r)
TYPE is a reserved word. This macro reduces to a constant. :)
I'll take a further look at the rest as I have time...
Posted on 2003-01-08 21:24:55 by bitRAKE
I noticed this and other stuff with the macros, so i abondonded your code (in some cases) and simply translated it for you from the #defines in the comments.

I have one major concern. The C++ macro:
;#define IoGetNextIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation - 1 )


Looks odd. Get the current address pointer, then subtract one from the address? One BYTE? If the stack is aligned on DWORDS then the alignment will be thrown off! However, im translating it literally! It may be 1 (DWORD) in which case you need to change it to 'sub eax, 4' instead...

The problem is, i dont know what these macro's do, or what the structures look like that they operater on.


Another think is i dont know why you need three parameters for status in the IoSetCompletionRoutine. But since C++ is doing this im assuming its an interfacing issue from other macros per se.

Lastly i use EBX soley for structure accessing. This is to keep a consistancy up so you can rely on edi, and esi if need be. This is also why i push/pop esi, edi in the copy routine. From a users point of view, they should only have to memorize "dont use EBX cause it will be corrupted, and be ready for returns in EAX"...

;++

;
; PIO_STACK_LOCATION
; IoGetCurrentIrpStackLocation(
; IN PIRP Irp
; )
;
; Routine Description:
;
; This routine is invoked to return a pointer to the current stack location
; in an I/O Request Packet (IRP).
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet.
;
; Return Value:
;
; The function value is a pointer to the current stack location in the
; packet.
;
;--
;#define IoMarkIrpPending( Irp ) ( IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED )
;
IoMarkIrpPending MACRO pIrp:REQ
mov ebx, pIrp
mov eax, (_IRP PTR [ebx]).CurrentStackLocation
or (IO_STACK_LOCATION PTR [eax]).Control, SL_PENDING_RETURNED
ENDM

IoGetCurrentIrpStackLocation MACRO pIrp:REQ
mov ebx, pIrp
mov eax, (_IRP PTR [ebx]).CurrentStackLocation
EXITM <eax>
ENDM

;++
;
; VOID
; IoSkipCurrentIrpStackLocation (
; IN PIRP Irp
; )
;
; Routine Description:
;
; This routine is invoked to increment the current stack location of
; a given IRP.
;
; If the caller wishes to call the next driver in a stack, and does not
; wish to change the arguments, nor does he wish to set a completion
; routine, then the caller first calls IoSkipCurrentIrpStackLocation
; and the calls IoCallDriver.
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet.
;
; Return Value:
;
; None
;
;--
;#define IoSkipCurrentIrpStackLocation( Irp ) \
; (Irp)->CurrentLocation++; \
; (Irp)->Tail.Overlay.CurrentStackLocation++;
;
IoSkipCurrentIrpStackLocation MACRO pIrp:REQ
mov ebx, pIrp
inc (_IRP PTR [ebx]).CurrentLocation
inc (_IRP PTR [ebx]).Tail.Overlay.CurrentStackLocation
ENDM

;++
;
; PIO_STACK_LOCATION
; IoGetNextIrpStackLocation(
; IN PIRP Irp
; )
;
; Routine Description:
;
; This routine is invoked to return a pointer to the next stack location
; in an I/O Request Packet (IRP).
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet.
;
; Return Value:
;
; The function value is a pointer to the next stack location in the packet.
;
;--
;#define IoGetNextIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation - 1 )
;
IoGetNextIrpStackLocation MACRO pIrp:REQ
mov ebx, pIrp
mov eax, (_IRP PTR [ebx]).Tail.Overlay.CurrentStackLocation
dec eax
EXITM <eax>
ENDM


;++
;
; VOID
; IoCopyCurrentIrpStackLocationToNext(
; IN PIRP Irp
; )
;
; Routine Description:
;
; This routine is invoked to copy the IRP stack arguments and file
; pointer from the current IrpStackLocation to the next
; in an I/O Request Packet (IRP).
;
; If the caller wants to call IoCallDriver with a completion routine
; but does not wish to change the arguments otherwise,
; the caller first calls IoCopyCurrentIrpStackLocationToNext,
; then IoSetCompletionRoutine, then IoCallDriver.
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet.
;
; Return Value:
;
; None.
;
;--
;
;#define IoCopyCurrentIrpStackLocationToNext( Irp ) { \
; PIO_STACK_LOCATION irpSp; \
; PIO_STACK_LOCATION nextIrpSp; \
; irpSp = IoGetCurrentIrpStackLocation( (Irp) ); \
; nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); \
; RtlCopyMemory( nextIrpSp, irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \
; nextIrpSp->Control = 0; }
;
IoCopyCurrentIrpStackLocationToNext MACRO pIrp:REQ
push esi
push edi
mov ebx, pIrp
;; irpSp = IoGetCurrentIrpStackLocation( (Irp) );
mov esi, (_IRP PTR [ebx]).CurrentStackLocation
;; nextIrpSp = IoGetNextIrpStackLocation( (Irp) );
mov edi, (_IRP PTR [ebx]).Tail.Overlay.CurrentStackLocation
dec edi
invoke RtlCopyMemory, edi, esi, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)
xor eax, eax
mov (IO_STACK_LOCATION PTR [edi]).Control, eax ;; xor is less byts than "mov xxx, 0"
pop edi
pop esi
ENDM

;++
;
; VOID
; IoSetCompletionRoutine(
; IN PIRP Irp,
; IN PIO_COMPLETION_ROUTINE CompletionRoutine,
; IN PVOID Context,
; IN BOOLEAN InvokeOnSuccess,
; IN BOOLEAN InvokeOnError,
; IN BOOLEAN InvokeOnCancel
; )
;
; Routine Description:
;
; This routine is invoked to set the address of a completion routine which
; is to be invoked when an I/O packet has been completed by a lower-level
; driver.
;
; Arguments:
;
; Irp - Pointer to the I/O Request Packet itself.
;
; CompletionRoutine - Address of the completion routine that is to be
; invoked once the next level driver completes the packet.
;
; Context - Specifies a context parameter to be passed to the completion
; routine.
;
; InvokeOnSuccess - Specifies that the completion routine is invoked when the
; operation is successfully completed.
;
; InvokeOnError - Specifies that the completion routine is invoked when the
; operation completes with an error status.
;
; InvokeOnCancel - Specifies that the completion routine is invoked when the
; operation is being canceled.
;
; Return Value:
;
; None.
;
;--
;
;#define IoSetCompletionRoutine( Irp, Routine, CompletionContext, Success, Error, Cancel ) { \
; PIO_STACK_LOCATION irpSp; \
; ASSERT( (Success) | (Error) | (Cancel) ? (Routine) != NULL : TRUE ); \
; irpSp = IoGetNextIrpStackLocation( (Irp) ); \
; irpSp->CompletionRoutine = (Routine); \
; irpSp->Context = (CompletionContext); \
; irpSp->Control = 0; \
; if ((Success)) { irpSp->Control = SL_INVOKE_ON_SUCCESS; } \
; if ((Error)) { irpSp->Control |= SL_INVOKE_ON_ERROR; } \
; if ((Cancel)) { irpSp->Control |= SL_INVOKE_ON_CANCEL; } }

IoSetCompletionRoutine MACRO pIrp:REQ, Routine:REQ, \
CompletionContext:REQ, \
Success:REQ, Error:REQ, \
Cancel:REQ

mov ebx, IoGetNextIrpStackLocation( pIrp )
mov eax, DWORD PTR Routine ;; Incase a memory address is given as 'routine'
mov (IO_STACK_LOCATION PTR [ebx]).CompletionRoutine, eax ;; Now "mov mem, reg" (always successful)
mov eax, DWORD PTR CompletionContext
mov (IO_STACK_LOCATION PTR [ebx]).Context, eax
xor eax, eax ;; better than "mov mem, 00000000h"
mov (IO_STACK_LOCATION PTR [ebx]).Control, eax

.IF Success
mov (IO_STACK_LOCATION PTR [ebx]).Control, SL_INVOKE_ON_SUCCESS
.ENDIF

.IF Error
or (IO_STACK_LOCATION PTR [ebx]).Control, SL_INVOKE_ON_ERROR
.ENDIF

.IF Cancel
or (IO_STACK_LOCATION PTR [ebx]).Control, SL_INVOKE_ON_CANCEL
.ENDIF

ENDM

;
; Calculate the byte offset of a field in a structure of type 'type'.
;
;#define FIELD_OFFSET(type, field) ((LONG)(LONG_PTR)&(((type *)0)->field))

FIELD_OFFSET MACRO struc_name:REQ, member_field:REQ
EXITM %(struc_name&.&member_field&)
ENDM

-------------------------------------------------------------------------------

Anywho, hope this is some help ;)
:alright:
NaN
Posted on 2003-01-08 21:54:17 by NaN
1. The DDK stands that IoGetCurrentIrpStackLocation is "routine".
We know it's not true, but...
When driver writer read this he might expect esi, edi, ebx are preserved.
It's very very bad, IMHO, to use these regs in macro.
You will get BSOD in very short order.

I use this macro in my ntddk.inc
IoGetCurrentIrpStackLocation MACRO pIrp:REQ

IFDIFI <pIrp>, <eax> ;; don't move eax onto itself
mov eax, pIrp
ENDIF
mov eax, (_IRP PTR [eax]).Tail.Overlay.CurrentStackLocation
ENDM
I have not defined other *IrpStackLocation macros because i don't need them.
If you will do, please hardly try to use only eax register.
And never esi, edi, ebx

2.
mov esi, (_IRP PTR [edi]).CurrentStackLocation

CurrentStackLocation ia a field of nested structure Overlay but not the field of _IPR itself.
It tells me you use incorrectly defined _IRP structure.

Mine is below:
;:::::::::::::::::::::::::::::::::::::::::

; I/O Request Packet (IRP) definition
;:::::::::::::::::::::::::::::::::::::::::

_IRP STRUCT ; sizeof = 70h
fwType WORD ?
cbSize WORD ? ; 02h

; Define the common fields used to control the IRP.

; Define a pointer to the Memory Descriptor List (MDL) for this I/O
; request. This field is only used if the I/O is "direct I/O".

MdlAddress PVOID ? ; 04h PMDL

; Flags word - used to remember various flags.

Flags DWORD ? ; 08h

; The following union is used for one of three purposes:
;
; 1. This IRP is an associated IRP. The field is a pointer to a master IRP.
;
; 2. This is the master IRP. The field is the count of the number of
; IRPs which must complete (associated IRPs) before the master can
; complete.
;
; 3. This operation is being buffered and the field is the address of
; the system space buffer.

UNION AssociatedIrp
MasterIrp PVOID ? ; 0Ch PIRP
IrpCount DWORD ? ; 0Ch
SystemBuffer PVOID ? ; 0Ch
ENDS ; AssociatedIrp

; Thread list entry - allows queueing the IRP to the thread pending I/O
; request packet list.

ThreadListEntry LIST_ENTRY <> ; 10h

; I/O status - final status of operation.

IoStatus IO_STATUS_BLOCK <> ; 18h

; Requestor mode - mode of the original requestor of this operation.

RequestorMode BYTE ? ; 20h KPROCESSOR_MODE

; Pending returned - TRUE if pending was initially returned as the
; status for this packet.

PendingReturned BYTE ? ; 21h

; Stack state information.

StackCount BYTE ? ; 22h
CurrentLocation BYTE ? ; 23h

; Cancel - packet has been canceled.

Cancel BYTE ? ; 24h

; Cancel Irql - Irql at which the cancel spinlock was acquired.

CancelIrql BYTE ? ; 25h

; ApcEnvironment - Used to save the APC environment at the time that the
; packet was initialized.

ApcEnvironment BYTE ? ; 26h

; Allocation control flags.

AllocationFlags BYTE ? 27h

; User parameters.

UserIosb PIO_STATUS_BLOCK ? ; 28h
UserEvent PKEVENT ? ; 2Ch
UNION Overlay ; 30h
STRUCT AsynchronousParameters ; 30h
UserApcRoutine PVOID ? ; 30h PIO_APC_ROUTINE
UserApcContext PVOID ? ; 34h
ENDS ; AsynchronousParameters
AllocationSize LARGE_INTEGER <> ; 30h
ENDS ; Overlay

; CancelRoutine - Used to contain the address of a cancel routine supplied
; by a device driver when the IRP is in a cancelable state.

CancelRoutine PVOID ? ; 38h PDRIVER_CANCEL

; Note that the UserBuffer parameter is outside of the stack so that I/O
; completion can copy data back into the user's address space without
; having to know exactly which service was being invoked. The length
; of the copy is stored in the second half of the I/O status block. If
; the UserBuffer field is NULL, then no copy is performed.

UserBuffer PVOID ? ; 3Ch

; Kernel structures
;
; The following section contains kernel structures which the IRP needs
; in order to place various work information in kernel controller system
; queues. Because the size and alignment cannot be controlled, they are
; placed here at the end so they just hang off and do not affect the
; alignment of other fields in the IRP.

UNION Tail
STRUCT Overlay
UNION
; DeviceQueueEntry - The device queue entry field is used to
; queue the IRP to the device driver device queue.

DeviceQueueEntry KDEVICE_QUEUE_ENTRY <>

STRUCT
; The following are available to the driver to use in
; whatever manner is desired, while the driver owns the
; packet.
DriverContext PVOID 4 dup(?)
ENDS

ENDS

; Thread - pointer to caller's Thread Control Block.

Thread PVOID ? ; PETHREAD

; Auxiliary buffer - pointer to any auxiliary buffer that is
; required to pass information to a driver that is not contained
; in a normal buffer.

AuxiliaryBuffer PCHAR ?

; The following unnamed structure must be exactly identical
; to the unnamed structure used in the minipacket header used
; for completion queue entries.

STRUCT

; List entry - used to queue the packet to completion queue, among
; others.

ListEntry LIST_ENTRY <>

UNION

; Current stack location - contains a pointer to the current
; IO_STACK_LOCATION structure in the IRP stack. This field
; should never be directly accessed by drivers. They should
; use the standard functions.
CurrentStackLocation PVOID ? ; PTR IO_STACK_LOCATION

; Minipacket type.

PacketType DWORD ?
ENDS
ENDS

; Original file object - pointer to the original file object
; that was used to open the file. This field is owned by the
; I/O system and should not be used by any other drivers.

OriginalFileObject PFILE_OBJECT ?

ENDS ; Overlay

; APC - This APC control block is used for the special kernel APC as
; well as for the caller's APC, if one was specified in the original
; argument list. If so, then the APC is reused for the normal APC for
; whatever mode the caller was in and the "special" routine that is
; invoked before the APC gets control simply deallocates the IRP.

Apc KAPC <>

; CompletionKey - This is the key that is used to distinguish
; individual I/O operations initiated on a single file handle.

CompletionKey PVOID ?

ENDS ;Tail

_IRP ENDS
PIRP typedef PTR _IRP
Posted on 2003-01-09 05:22:51 by Four-F
Originally posteb by bitRake
TYPE is a reserved word. This macro reduces to a constant


Thanks for point this out to me. I feel like such a newbie when it comes to this macro stuff :)

Originally posteb by NaN
I have one major concern. The C++ macro:
;#define IoGetNextIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation - 1 )


This is how it is defined inside the wdm.h file.

Originally posteb by
Lastly i use EBX soley for structure accessing. This is to keep a consistancy up so you can rely on edi, and esi if need be. This is also why i push/pop esi, edi in the copy routine. From a users point of view, they should only have to memorize "dont use EBX cause it will be corrupted, and be ready for returns in EAX"...


Thanks for the excellent tip! I am learning so much from all of the response. Heck in no time I will be a macro programming master :) -- NOT. I can see, though, I do have alot of work ahead of me to figuring out the proper use and definitions of macros. Its just that I have spent so much time not using macros that grasping the use seems to be difficult (maybe it's that I am just going crazy :) )



It's very very bad, IMHO, to use these regs in macro.
You will get BSOD in very short order.


Thanks for the tip! as it is well noted as I truly do not
build and use macros that much (I am a baddddd little boy :) )



I have not defined other *IrpStackLocation macros because i don't need them.
If you will do, please hardly try to use only eax register.
And never esi, edi, ebx


I never really use them either! What I was trying to do was to make the Win32ASM code
read like the C code and then within the text document I was going to explain that you
really did not need to use them as this is all that they were I was just thinking that
the more the source codes look and feel alike the the easier it would be for people
to concentrate on the meat of the text document rather than spending their time in
figuring out the differences in the way the code is layed out.



CurrentStackLocation ia a field of nested structure Overlay but not the field of _IPR itself.
It tells me you use incorrectly defined _IRP structure.


Your right, stupid me I failed to notice what I had done wrong :eek: As you can see from the below code snippet (my version of _IRP) I had the UNION's and Structs as no names (I failed to remove the ; before the name of the UNION) :rolleyes: and if you do not mind I would like to use your corrected version in my future projects.

Thanks for pointing that out!



_IRP Struct
irpType WORD ? ;+000h
irpSize WORD ? ;+002h
MdlAddress pMDL ? ;+004h
Flags DWORD ? ;+008h
UNION ;AssociatedIrp
MasterIrp pIRP ? ;+00Ch
IrpCount DWORD ? ;+00Ch
SystemBuffer pVOID ? ;+00Ch
ENDS ; AssociatedIrp
ThreadListEntry LIST__ENTRY <> ;+010h
IoStatus IO_STATUS_BLOCK <> ;+018h
RequestorMode BYTE ? ;+020h
PendingReturned BYTE ? ;+021h
StackCount BYTE ? ;+022h
CurrentLocation BYTE ? ;+023h
Cancel BYTE ? ;+024h
CancelIrql BYTE ? ;+025h
ApcEnvironment BYTE ? ;+026h
AllocationFlags BYTE ? ;+027h
UserIosb pIO_STATUS_BLOCK ? ;+028h
UserEvent pKEVENT ? ;+02Ch
UNION ;Overlay
STRUCT ;AsynchronousParameters
UserApcRoutine pFunction ? ;+030h
UserApcContext pVOID ? ;+034h
ENDS ;AsynchronousParameters
AllocationSize LARGE_INT <> ;+030h
ENDS
CancelRoutine pFunction ? ;+038h
UserBuffer pVOID ? ;+03Ch
UNION ;Tail
STRUCT ;Overlay
DeviceQueueEntry KDEVICE_QUEUE_ENTRY <> ;+040h
ENDS ;Overlay
STRUCT
DriverContext pVOID 4 DUP (?) ;+040h
Thread pETHREAD ? ;+050h
AuxiliaryBuffer DWORD ? ;+054h
ListEntry LIST__ENTRY <> ;+058h
UNION
CurrentStackLocation pIO_STACK_LOCATION ? ;+060h
PacketType DWORD ? ;+060h
ENDS
OriginalFileObject pFILE_OBJECT ? ;+064h
ENDS
UNION
Apc KAPC <> ;+040h
CompletionKey pVOID ? ;+040h
ENDS
ENDS ;Tail
_IRP ENDS


;-------------------------

Now for one last Macro question, does anyone already have a macro for ASSERT?

Again, I can not begin to tell each of you how much I appreciate your help. Not only has it helped me to get a better understanding of one of my weak points (macros) but it has also helped out greatly in the development process of my WDM tutorial (I would have spent a long time trying to figure out what was wrong with the macro code).

Have a good day (or night - depending on where you are at).:alright:
Posted on 2003-01-09 10:16:32 by madprgmr
Originally posted by NaN
I noticed this and other stuff with the macros, so i abondonded your code (in some cases) and simply translated it for you from the #defines in the comments.

I have one major concern. The C++ macro:
;#define IoGetNextIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation - 1 )


Looks odd. Get the current address pointer, then subtract one from the address? One BYTE? If the stack is aligned on DWORDS then the alignment will be thrown off! However, im translating it literally! It may be 1 (DWORD) in which case you need to change it to 'sub eax, 4' instead...

The problem is, i dont know what these macro's do, or what the structures look like that they operater on.

;--
;#define IoSkipCurrentIrpStackLocation( Irp ) \
; (Irp)->CurrentLocation++; \
; (Irp)->Tail.Overlay.CurrentStackLocation++;
;
IoSkipCurrentIrpStackLocation MACRO pIrp:REQ
mov ebx, pIrp
inc (_IRP PTR ).CurrentLocation
inc (_IRP PTR ).Tail.Overlay.CurrentStackLocation
ENDM
I checked Oney (instead of wading through C++ code).
There is an array of IO_STACK_LOCATION structures, and CurrentLocation is an index into the structure, while CurrentStackLocation is a pointer to the same entry. Consequently, the last inc must be changed to an add:

add (_IRP PTR ).Tail.Overlay.CurrentStackLocation, SIZEOF IO_STACK_LOCATION

Similarly, the code for

;#define IoGetNextIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation - 1 )

will be

mov eax, (_IRP PTR ).Tail.Overlay.CurrentStackLocation
sub eax, SIZEOF IO_STACK_LOCATION
Posted on 2003-01-09 16:35:47 by tenkey
madprgmr,

Soo err, with the new KMD kit floating around I thought i would ask the question:

Hows the WDM tutorial going?? :grin:

:NaN:
Posted on 2003-01-22 21:44:49 by NaN

madprgmr,

Soo err, with the new KMD kit floating around I thought i would ask the question:

Hows the WDM tutorial going?? :grin:

:NaN:


I am sorry to say that it is comming rather slowly as I have been sick with the Flu on-top-of a large amount of extra work at work and dealing with the adoption process. :(

I will try to work on it some more this weekend.
Posted on 2003-01-23 09:22:26 by madprgmr
Take your time... im just happy there *is* work being done. Those who know it dont seem to write tutorials for it (i assume cause its kinda complicated to explain properly ).

Anywho, dont feel rushed; i was just currious..
:alright:
:NaN:
Posted on 2003-01-23 16:33:26 by NaN
All:

Just thought that I would give you a little update as to the Wdm Tut progress:

At this time I am currently almost done with the debugging of the Win32ASM version of the driver (taking a little more time than I wanted but its getting done). As for the text portion of this tut, this has been started but is still in it's infancy.

I realize that this is taking a long time and all that I can offer you in terms of support is that it will be worth the wait.

:alright:
Posted on 2003-02-10 18:34:04 by madprgmr