2 * Copyright (C) 2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
4 * This file is part of WinVBlock, derived from WinAoE.
5 * For WinAoE contact information, see http://winaoe.org/
7 * WinVBlock is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * WinVBlock is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with WinVBlock. If not, see <http://www.gnu.org/licenses/>.
30 #include "winvblock.h"
37 * An internal type. A device extension will have a
38 * pointer to this structure, but its type will be a void pointer
40 winvblock__def_struct ( handler_chain )
43 * Points to an array of irp__handlings
47 * Total table size, in bytes
51 * Points to the next table in the chain or NULL
53 handler_chain_ptr next;
57 * Register an IRP handling table with a chain (with table size)
59 * @v chain_ptr Pointer to IRP handler chain to attach a table to
60 * @v table Table to add
61 * @v size Size of the table to add, in bytes
62 * @ret FALSE for failure, TRUE for success
64 winvblock__lib_func winvblock__bool
66 IN OUT irp__handler_chain_ptr chain_ptr,
67 IN irp__handling_ptr table,
72 * The type used by a device extension is opaque
74 handler_chain_ptr *link = ( handler_chain_ptr * ) chain_ptr,
79 * Nothing to attach to
83 * Allocate and attach a new link in the chain.
84 * Maybe we should use a spin-lock for this
86 new_link = ExAllocatePool ( NonPagedPool, sizeof ( handler_chain ) );
87 if ( new_link == NULL )
92 DBG ( "Could not allocate IRP handler chain!\n" );
96 new_link->table = table;
98 * Could sanity-check the size to be a multiple of sizeof(irp__handling)
100 new_link->size = size;
101 new_link->next = *link;
107 * Un-register an IRP handling table from a chain
109 * @v chain_ptr Pointer to IRP handler chain to remove table from
110 * @v table Table to remove
111 * @ret FALSE for failure, TRUE for success
113 winvblock__lib_func winvblock__bool
115 IN OUT irp__handler_chain_ptr chain_ptr,
116 IN irp__handling_ptr table
119 winvblock__bool done = FALSE;
121 * The type used by a device extension is opaque
123 handler_chain_ptr *link = ( handler_chain_ptr * ) chain_ptr;
131 * Walk the chain, looking for the given table
133 while ( *link != NULL )
135 if ( link[0]->table == table )
138 * Remove this link in the chain
140 handler_chain_ptr next = link[0]->next;
141 ExFreePool ( *link );
145 link = &link[0]->next;
148 DBG ( "Table not found\n" );
153 * Mini IRP handling strategy
156 irp__handler_decl ( irp__process )
158 NTSTATUS status = STATUS_NOT_SUPPORTED;
159 size_t irp_handler_index;
162 * Determine the device's IRP handler stack size
164 irp_handler_index = DeviceExtension->irp_handler_stack_size;
167 * For each entry in the stack, in top-down order
169 while ( irp_handler_index-- )
171 irp__handling handling;
172 winvblock__bool handles_major,
176 * Get the handling entry
178 handling = DeviceExtension->irp_handler_stack_ptr[irp_handler_index];
180 handles_major = ( Stack->MajorFunction == handling.irp_major_func )
181 || handling.any_major;
182 handles_minor = ( Stack->MinorFunction == handling.irp_minor_func )
183 || handling.any_minor;
184 if ( handles_major && handles_minor )
186 handling.handler ( DeviceObject, Irp, Stack, DeviceExtension,
189 * Do not process the IRP any further down the stack
191 if ( *completion_ptr )