I found this in a book about WDM Driver programming:

Win32 executable files, including kernel-mode drivers, are internally composed of one or more
sections. A section can contain code or data and, generally speaking, has additional attributes
such as being readable, writable, sharable, executable, and so on. A section is also the smallest
unit that you can designate when you're specifying pagability. When loading a driver image, the
system puts sections whose literal names begin with "page" or ".eda" (the start of ".edata") into
the paged pool

Questions:

How can I make one section of my driver to be loaded in to the NONPAGED pool WITHOUT using
the MmLockPagableCodeSection and MmLockPagableDataSection functions?

There are some section name that makes the Driver to be loaded in to the NONPAGED POOL?
Posted on 2004-02-09 07:34:56 by Opcode
Yes, these section names were listed in an obvious place. I don't remember the names, nor I'd like to download the DDK and install it, but there are such sections for sure. The place, where the driver is initiated, is always in a non-paged section
Posted on 2004-02-09 11:37:09 by Ultrano
hmm looking at an old project of mine, the section entering macros are
VxD_LOCKED_DATA_SEG
VxD_LOCKED_DATA_ENDS
VxD_LOCKED_CODE_SEG
VxD_LOCKED_CODE_ENDS
this is for '98
Posted on 2004-02-09 11:40:25 by Ultrano
Thanks for the effort, Ultrano, but the MmLockPagableCodeSection
and MmLockPagableDataSection functions if from Windows NT/2k/XP DDK,
they don?t exist for VxD programming.
Posted on 2004-02-09 12:07:13 by Opcode
Hi

Reading a little further along in that document (from Programming the MS Windows Driver Model), it looks like the code and data sections are in NON-PAGEABLE sections by default anyway. It goes on to say if you want to override the default compiling you can set that with a #pragma statement (not sure how that would convert to a MASM statement):

The traditional way of telling the compiler to put code into a particular section is to use the alloc_text pragma. Since not every compiler will necessarily support the pragma, the DDK headers either define or don?t define the constant ALLOC_PRAGMA to tell you whether to use the pragma. You can then invoke the pragma to specify the section placement of individual subroutines in your driver, as follows:

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, AddDevice)
#pragma alloc_text(PAGE, DispatchPnp)
#endif

These statements serve to place the AddDevice and DispatchPnp functions into the paged pool.

To control the placement of data variables, you use a different pragma under the control of a different preprocessor macro symbol:

#ifdef ALLOC_DATA_PRAGMA
#pragma data_seg("PAGEDATA")
#endif
The data_seg pragma causes all static data variables declared in a source module after the appearance of the pragma to go into the paged pool.

To revert to the default code section, just code #pragma code_seg with no argument:
#pragma code_seg()
Similarly, to revert to the regular nonpaged data section, code #pragma data_seg with no argument:
#pragma data_seg()



Now, in looking at the section characteristics of one of my drivers it appears the .text, .data, and .rdata sections all have the NON-PAGEABLE flag (08000000) set by default in MASM with no extra linking options. I use the following:

LINK /ENTRY:DriverEntry /driver /base:0x10000 /align:32 /subsystem:native /OUT:%drv1%.sys %drv%.obj /DEBUG /DEBUGTYPE:CV

The only section that compiles as PAGEABLE (except for .reloc) is the INIT section, which happens to be the IAT. Like other PE's, the Import table is initialized by the PE loader, and thereafter exist hardcoded as absolute addresses residing in the non-paged .rdata section. You can see all this with a PE editor and disassembly. Interestingly, the .text and INIT sections are mapped as CODE, the rest as IDATA types.

So it seems you don't have to specify NON-PAGEABLE in general, instead just the opposite. One thing that would be nice to control though is being able to put your DriverEntry routine in the INIT section,

...you can also direct code into the INIT section if it?s not needed once your driver finishes initializing. For example:

#pragma alloc_text(INIT, DriverEntry)
This statement forces the DriverEntry function into the INIT section. The system will release the memory it occupies when it returns.


I'm not sure how one would declare that though since LINK.exe doesn't seem to support the /SECTION specifier with an INIT section. Maybe someone has some further ideas in controlling the compile options for drivers.

Kayaker
Posted on 2004-02-09 18:24:21 by Kayaker
Whole driver's image is nonpageable by default. You don't have to do any special for this. If you want to make some part of the driver to be discardable as needed use section names starting with "PAGE". Initializing code can be placed into "INIT" section and also will be paged. Masm smart enough and you can use names right in .code directive for naming code sections like this:
.code INIT
Unfortunatelly only .code directive supports this feature. For data sections use common SEGMENT directive.

;@echo off

;goto make

.386
.model flat, stdcall
option casemap:none

include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc

include \masm32\include\w2k\ntoskrnl.inc

includelib \masm32\lib\w2k\ntoskrnl.lib

;::::::::::::::::::::::::::::: PAGED DATA ::::::::::::::::::::::::::::::::

PAGEDAT1 SEGMENT
PagedDword1 DWORD 0
PAGEDAT1 ENDS

PAGEDAT2 SEGMENT
PagedDword2 DWORD 0
PAGEDAT2 ENDS

;::::::::::::::::::::::::::: NONPAGED DATA :::::::::::::::::::::::::::::::

.data
NonpagedDword DWORD 0

;::::::::::::::::::::::::::: NONPAGED CODE :::::::::::::::::::::::::::::::

.code

NonpageableProc proc
mov eax, NonpagedDword
ret
NonpageableProc endp

;::::::::::::::::::::::::::::: PAGED CODE ::::::::::::::::::::::::::::::::

.code PAGED1

PageableProc1 proc
mov eax, PagedDword1
ret
PageableProc1 endp

.code PAGED2

PageableProc2 proc
mov eax, PagedDword2
ret
PageableProc2 endp

.code INIT

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
ret
DriverEntry endp

end DriverEntry

:make

set drv=skeleton

\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /out:%drv%.sys /subsystem:native /ignore:4078 %drv%.obj

del %drv%.obj

echo.
pause

PS: And don't use /align:32 linker option as I usually do while compiling drivers. If you do, multiple sections with different attributes will be placed into one memory page (4Kb). If only one very small section marked as nonpaged whole 4Kb will be nonpaged.
Posted on 2004-02-10 04:04:18 by Four-F
I had understood badly the text of Walter Oney.
I thought that name PAGE in the section would make with that it
was placed in PAGED POOL memory.

Thanks again, Kayaker and Four-F ! :alright: :alright: :alright:
I wait to always be able to find its precious aids in this forum.
Posted on 2004-02-10 05:02:05 by Opcode