Don't call DriverEntry more than once. Fix suggested by Filip Navara.
[reactos.git] / reactos / ntoskrnl / include / internal / io.h
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2000 David Welch <welch@cwcom.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: include/internal/io.h
24 * PURPOSE: Internal io manager declarations
25 * PROGRAMMER: David Welch (welch@mcmail.com)
26 * UPDATE HISTORY:
27 * 28/05/97: Created
28 */
29
30 #ifndef __NTOSKRNL_INCLUDE_INTERNAL_IO_H
31 #define __NTOSKRNL_INCLUDE_INTERNAL_IO_H
32
33 #include <ddk/ntddk.h>
34 #include <internal/ob.h>
35 #include <internal/module.h>
36
37
38 #ifndef __USE_W32API
39 #define DEVICE_TYPE_FROM_CTL_CODE(ctlCode) (((ULONG)(ctlCode&0xffff0000))>>16)
40 #endif
41
42 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
43
44
45 typedef struct _IO_COMPLETION_PACKET{
46 PVOID Key;
47 PVOID Context;
48 IO_STATUS_BLOCK IoStatus;
49 LIST_ENTRY ListEntry;
50 } IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET;
51
52 typedef struct _DEVOBJ_EXTENSION {
53 CSHORT Type;
54 USHORT Size;
55 PDEVICE_OBJECT DeviceObject;
56 ULONG Unknown[3];
57 struct _DEVICE_NODE *DeviceNode;
58 } DEVOBJ_EXTENSION, *PDEVOBJ_EXTENSION;
59
60 typedef struct _PRIVATE_DRIVER_EXTENSIONS {
61 struct _PRIVATE_DRIVER_EXTENSIONS *Link;
62 PVOID ClientIdentificationAddress;
63 CHAR Extension[1];
64 } PRIVATE_DRIVER_EXTENSIONS, *PPRIVATE_DRIVER_EXTENSIONS;
65
66 typedef struct _DEVICE_NODE
67 {
68 /* A tree structure. */
69 struct _DEVICE_NODE *Parent;
70 struct _DEVICE_NODE *PrevSibling;
71 struct _DEVICE_NODE *NextSibling;
72 struct _DEVICE_NODE *Child;
73 /* The level of deepness in the tree. */
74 UINT Level;
75 /* */
76 // PPO_DEVICE_NOTIFY Notify;
77 /* State machine. */
78 // PNP_DEVNODE_STATE State;
79 // PNP_DEVNODE_STATE PreviousState;
80 // PNP_DEVNODE_STATE StateHistory[20];
81 // UINT StateHistoryEntry;
82 /* ? */
83 INT CompletionStatus;
84 /* ? */
85 PIRP PendingIrp;
86 /* See DNF_* flags below (WinDBG documentation has WRONG values) */
87 ULONG Flags;
88 /* See DNUF_* flags below (and IRP_MN_QUERY_PNP_DEVICE_STATE) */
89 ULONG UserFlags;
90 /* See CM_PROB_* values are defined in cfg.h */
91 ULONG Problem;
92 /* Pointer to the PDO corresponding to the device node. */
93 PDEVICE_OBJECT PhysicalDeviceObject;
94 /* Resource list as assigned by the PnP arbiter. See IRP_MN_START_DEVICE
95 and ARBITER_INTERFACE (not documented in DDK, but present in headers). */
96 PCM_RESOURCE_LIST ResourceList;
97 /* Resource list as assigned by the PnP arbiter (translated version). */
98 PCM_RESOURCE_LIST ResourceListTranslated;
99 /* Instance path relative to the Enum key in registry. */
100 UNICODE_STRING InstancePath;
101 /* Name of the driver service. */
102 UNICODE_STRING ServiceName;
103 /* ? */
104 PDEVICE_OBJECT DuplicatePDO;
105 /* See IRP_MN_QUERY_RESOURCE_REQUIREMENTS. */
106 PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements;
107 /* Information about bus for bus drivers. */
108 INTERFACE_TYPE InterfaceType;
109 ULONG BusNumber;
110 /* Information about underlying bus for child devices. */
111 INTERFACE_TYPE ChildInterfaceType;
112 ULONG ChildBusNumber;
113 USHORT ChildBusTypeIndex;
114 /* ? */
115 UCHAR RemovalPolicy;
116 UCHAR HardwareRemovalPolicy;
117 LIST_ENTRY TargetDeviceNotify;
118 LIST_ENTRY DeviceArbiterList;
119 LIST_ENTRY DeviceTranslatorList;
120 USHORT NoTranslatorMask;
121 USHORT QueryTranslatorMask;
122 USHORT NoArbiterMask;
123 USHORT QueryArbiterMask;
124 union {
125 struct _DEVICE_NODE *LegacyDeviceNode;
126 PDEVICE_RELATIONS PendingDeviceRelations;
127 } OverUsed1;
128 union {
129 struct _DEVICE_NODE *NextResourceDeviceNode;
130 } OverUsed2;
131 /* See IRP_MN_QUERY_RESOURCES/IRP_MN_FILTER_RESOURCES. */
132 PCM_RESOURCE_LIST BootResources;
133 /* See the bitfields in DEVICE_CAPABILITIES structure. */
134 ULONG CapabilityFlags;
135 struct
136 {
137 ULONG DockStatus;
138 LIST_ENTRY ListEntry;
139 WCHAR *SerialNumber;
140 } DockInfo;
141 ULONG DisableableDepends;
142 LIST_ENTRY PendedSetInterfaceState;
143 LIST_ENTRY LegacyBusListEntry;
144 ULONG DriverUnloadRetryCount;
145
146 /* Not NT's */
147 GUID BusTypeGuid;
148 ULONG Address;
149 } DEVICE_NODE, *PDEVICE_NODE;
150
151 /* For Flags field */
152 #define DNF_PROCESSED 0x00000001
153 #define DNF_STARTED 0x00000002
154 #define DNF_START_FAILED 0x00000004
155 #define DNF_ENUMERATED 0x00000008
156 #define DNF_DELETED 0x00000010
157 #define DNF_MADEUP 0x00000020
158 #define DNF_START_REQUEST_PENDING 0x00000040
159 #define DNF_NO_RESOURCE_REQUIRED 0x00000080
160 #define DNF_INSUFFICIENT_RESOURCES 0x00000100
161 #define DNF_RESOURCE_ASSIGNED 0x00000200
162 #define DNF_RESOURCE_REPORTED 0x00000400
163 #define DNF_HAL_NODE 0x00000800 // ???
164 #define DNF_ADDED 0x00001000
165 #define DNF_ADD_FAILED 0x00002000
166 #define DNF_LEGACY_DRIVER 0x00004000
167 #define DNF_STOPPED 0x00008000
168 #define DNF_WILL_BE_REMOVED 0x00010000
169 #define DNF_NEED_TO_ENUM 0x00020000
170 #define DNF_NOT_CONFIGURED 0x00040000
171 #define DNF_REINSTALL 0x00080000
172 #define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00100000 // ???
173 #define DNF_DISABLED 0x00200000
174 #define DNF_RESTART_OK 0x00400000
175 #define DNF_NEED_RESTART 0x00800000
176 #define DNF_VISITED 0x01000000
177 #define DNF_ASSIGNING_RESOURCES 0x02000000
178 #define DNF_BEEING_ENUMERATED 0x04000000
179 #define DNF_NEED_ENUMERATION_ONLY 0x08000000
180 #define DNF_LOCKED 0x10000000
181 #define DNF_HAS_BOOT_CONFIG 0x20000000
182 #define DNF_BOOT_CONFIG_RESERVED 0x40000000
183 #define DNF_HAS_PROBLEM 0x80000000 // ???
184
185 /* For UserFlags field */
186 #define DNUF_DONT_SHOW_IN_UI 0x0002
187 #define DNUF_NOT_DISABLEABLE 0x0008
188
189 /* For Problem field */
190 #define CM_PROB_NOT_CONFIGURED 1
191 #define CM_PROB_FAILED_START 10
192 #define CM_PROB_NORMAL_CONFLICT 12
193 #define CM_PROB_NEED_RESTART 14
194 #define CM_PROB_REINSTALL 18
195 #define CM_PROB_WILL_BE_REMOVED 21
196 #define CM_PROB_DISABLED 22
197 #define CM_PROB_FAILED_INSTALL 28
198 #define CM_PROB_FAILED_ADD 31
199
200 /*
201 * VOID
202 * IopDeviceNodeSetFlag(
203 * PDEVICE_NODE DeviceNode,
204 * ULONG Flag);
205 */
206 #define IopDeviceNodeSetFlag(DeviceNode, Flag)((DeviceNode)->Flags |= (Flag))
207
208 /*
209 * VOID
210 * IopDeviceNodeClearFlag(
211 * PDEVICE_NODE DeviceNode,
212 * ULONG Flag);
213 */
214 #define IopDeviceNodeClearFlag(DeviceNode, Flag)((DeviceNode)->Flags &= ~(Flag))
215
216 /*
217 * BOOLEAN
218 * IopDeviceNodeHasFlag(
219 * PDEVICE_NODE DeviceNode,
220 * ULONG Flag);
221 */
222 #define IopDeviceNodeHasFlag(DeviceNode, Flag)(((DeviceNode)->Flags & (Flag)) > 0)
223
224 /*
225 * VOID
226 * IopDeviceNodeSetUserFlag(
227 * PDEVICE_NODE DeviceNode,
228 * ULONG UserFlag);
229 */
230 #define IopDeviceNodeSetUserFlag(DeviceNode, UserFlag)((DeviceNode)->UserFlags |= (UserFlag))
231
232 /*
233 * VOID
234 * IopDeviceNodeClearUserFlag(
235 * PDEVICE_NODE DeviceNode,
236 * ULONG UserFlag);
237 */
238 #define IopDeviceNodeClearUserFlag(DeviceNode, UserFlag)((DeviceNode)->UserFlags &= ~(UserFlag))
239
240 /*
241 * BOOLEAN
242 * IopDeviceNodeHasUserFlag(
243 * PDEVICE_NODE DeviceNode,
244 * ULONG UserFlag);
245 */
246 #define IopDeviceNodeHasUserFlag(DeviceNode, UserFlag)(((DeviceNode)->UserFlags & (UserFlag)) > 0)
247
248 /*
249 * VOID
250 * IopDeviceNodeSetProblem(
251 * PDEVICE_NODE DeviceNode,
252 * ULONG Problem);
253 */
254 #define IopDeviceNodeSetProblem(DeviceNode, Problem)((DeviceNode)->Problem |= (Problem))
255
256 /*
257 * VOID
258 * IopDeviceNodeClearProblem(
259 * PDEVICE_NODE DeviceNode,
260 * ULONG Problem);
261 */
262 #define IopDeviceNodeClearProblem(DeviceNode, Problem)((DeviceNode)->Problem &= ~(Problem))
263
264 /*
265 * BOOLEAN
266 * IopDeviceNodeHasProblem(
267 * PDEVICE_NODE DeviceNode,
268 * ULONG Problem);
269 */
270 #define IopDeviceNodeHasProblem(DeviceNode, Problem)(((DeviceNode)->Problem & (Problem)) > 0)
271
272
273 /*
274 Called on every visit of a node during a preorder-traversal of the device
275 node tree.
276 If the routine returns STATUS_UNSUCCESSFUL the traversal will stop and
277 STATUS_SUCCESS is returned to the caller who initiated the tree traversal.
278 Any other returned status code will be returned to the caller. If a status
279 code that indicates an error (other than STATUS_UNSUCCESSFUL) is returned,
280 the traversal is stopped immediately and the status code is returned to
281 the caller.
282 */
283 typedef NTSTATUS (*DEVICETREE_TRAVERSE_ROUTINE)(
284 PDEVICE_NODE DeviceNode,
285 PVOID Context);
286
287 /* Context information for traversing the device tree */
288 typedef struct _DEVICETREE_TRAVERSE_CONTEXT
289 {
290 /* Current device node during a traversal */
291 PDEVICE_NODE DeviceNode;
292 /* Initial device node where we start the traversal */
293 PDEVICE_NODE FirstDeviceNode;
294 /* Action routine to be called for every device node */
295 DEVICETREE_TRAVERSE_ROUTINE Action;
296 /* Context passed to the action routine */
297 PVOID Context;
298 } DEVICETREE_TRAVERSE_CONTEXT, *PDEVICETREE_TRAVERSE_CONTEXT;
299
300 /*
301 * VOID
302 * IopInitDeviceTreeTraverseContext(
303 * PDEVICETREE_TRAVERSE_CONTEXT DeviceTreeTraverseContext,
304 * PDEVICE_NODE DeviceNode,
305 * DEVICETREE_TRAVERSE_ROUTINE Action,
306 * PVOID Context);
307 */
308 #define IopInitDeviceTreeTraverseContext( \
309 _DeviceTreeTraverseContext, _DeviceNode, _Action, _Context) { \
310 (_DeviceTreeTraverseContext)->FirstDeviceNode = (_DeviceNode); \
311 (_DeviceTreeTraverseContext)->Action = (_Action); \
312 (_DeviceTreeTraverseContext)->Context = (_Context); }
313
314
315 extern PDEVICE_NODE IopRootDeviceNode;
316 extern ULONG IoOtherOperationCount;
317 extern ULONGLONG IoOtherTransferCount;
318
319 VOID
320 PnpInit(VOID);
321
322 VOID
323 IopInitDriverImplementation(VOID);
324
325 NTSTATUS
326 IopGetSystemPowerDeviceObject(PDEVICE_OBJECT *DeviceObject);
327 NTSTATUS
328 IopCreateDeviceNode(PDEVICE_NODE ParentNode,
329 PDEVICE_OBJECT PhysicalDeviceObject,
330 PDEVICE_NODE *DeviceNode);
331 NTSTATUS
332 IopFreeDeviceNode(PDEVICE_NODE DeviceNode);
333
334 VOID
335 IoInitCancelHandling(VOID);
336 VOID
337 IoInitFileSystemImplementation(VOID);
338 VOID
339 IoInitVpbImplementation(VOID);
340
341 NTSTATUS
342 IoMountVolume(IN PDEVICE_OBJECT DeviceObject,
343 IN BOOLEAN AllowRawMount);
344 POBJECT IoOpenSymlink(POBJECT SymbolicLink);
345 POBJECT IoOpenFileOnDevice(POBJECT SymbolicLink, PWCHAR Name);
346
347 VOID STDCALL
348 IoSecondStageCompletion(
349 PKAPC Apc,
350 PKNORMAL_ROUTINE* NormalRoutine,
351 PVOID* NormalContext,
352 PVOID* SystemArgument1,
353 PVOID* SystemArgument2);
354
355 NTSTATUS STDCALL
356 IopCreateFile(PVOID ObjectBody,
357 PVOID Parent,
358 PWSTR RemainingPath,
359 POBJECT_ATTRIBUTES ObjectAttributes);
360 NTSTATUS STDCALL
361 IopCreateDevice(PVOID ObjectBody,
362 PVOID Parent,
363 PWSTR RemainingPath,
364 POBJECT_ATTRIBUTES ObjectAttributes);
365 NTSTATUS IoAttachVpb(PDEVICE_OBJECT DeviceObject);
366
367 PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
368 PDEVICE_OBJECT DeviceObject,
369 PMDL Mdl,
370 PLARGE_INTEGER StartingOffset,
371 PKEVENT Event,
372 PIO_STATUS_BLOCK IoStatusBlock,
373 BOOLEAN PagingIo);
374
375 VOID IoInitShutdownNotification(VOID);
376 VOID IoShutdownRegisteredDevices(VOID);
377 VOID IoShutdownRegisteredFileSystems(VOID);
378
379 NTSTATUS STDCALL
380 IoPageWrite(PFILE_OBJECT FileObject,
381 PMDL Mdl,
382 PLARGE_INTEGER Offset,
383 PKEVENT Event,
384 PIO_STATUS_BLOCK StatusBlock);
385
386 NTSTATUS
387 IoCreateArcNames(VOID);
388
389 NTSTATUS
390 IoCreateSystemRootLink(PCHAR ParameterLine);
391
392 NTSTATUS
393 IopInitiatePnpIrp(
394 PDEVICE_OBJECT DeviceObject,
395 PIO_STATUS_BLOCK IoStatusBlock,
396 ULONG MinorFunction,
397 PIO_STACK_LOCATION Stack);
398
399 BOOLEAN
400 IopCreateUnicodeString(
401 PUNICODE_STRING Destination,
402 PWSTR Source,
403 POOL_TYPE PoolType);
404
405
406 NTSTATUS
407 IoCreateDriverList(VOID);
408
409 NTSTATUS
410 IoDestroyDriverList(VOID);
411
412 /* bootlog.c */
413
414 VOID
415 IopInitBootLog(BOOLEAN StartBootLog);
416
417 VOID
418 IopStartBootLog(VOID);
419
420 VOID
421 IopStopBootLog(VOID);
422
423 VOID
424 IopBootLog(PUNICODE_STRING DriverName, BOOLEAN Success);
425
426 VOID
427 IopSaveBootLogToFile(VOID);
428
429 /* cancel.c */
430
431 VOID STDCALL
432 IoCancelThreadIo(PETHREAD Thread);
433
434 /* errlog.c */
435
436 NTSTATUS
437 IopInitErrorLog(VOID);
438
439
440 /* rawfs.c */
441
442 BOOLEAN
443 RawFsIsRawFileSystemDeviceObject(IN PDEVICE_OBJECT DeviceObject);
444
445 NTSTATUS STDCALL
446 RawFsDriverEntry(PDRIVER_OBJECT DriverObject,
447 PUNICODE_STRING RegistryPath);
448
449
450 /* pnproot.c */
451
452 NTSTATUS
453 STDCALL
454 PnpRootDriverEntry(
455 IN PDRIVER_OBJECT DriverObject,
456 IN PUNICODE_STRING RegistryPath);
457
458 NTSTATUS
459 PnpRootCreateDevice(
460 PDEVICE_OBJECT *PhysicalDeviceObject);
461
462 /* device.c */
463
464 NTSTATUS FASTCALL
465 IopInitializeDevice(
466 PDEVICE_NODE DeviceNode,
467 PDRIVER_OBJECT DriverObject);
468
469 /* driver.c */
470
471 VOID FASTCALL
472 IopInitializeBootDrivers(VOID);
473
474 VOID FASTCALL
475 IopInitializeSystemDrivers(VOID);
476
477 NTSTATUS FASTCALL
478 IopCreateDriverObject(
479 PDRIVER_OBJECT *DriverObject,
480 PUNICODE_STRING ServiceName,
481 ULONG CreateAttributes,
482 BOOLEAN FileSystemDriver,
483 PVOID DriverImageStart,
484 ULONG DriverImageSize);
485
486 NTSTATUS FASTCALL
487 IopLoadServiceModule(
488 IN PUNICODE_STRING ServiceName,
489 OUT PMODULE_OBJECT *ModuleObject);
490
491 NTSTATUS FASTCALL
492 IopInitializeDriverModule(
493 IN PDEVICE_NODE DeviceNode,
494 IN PMODULE_OBJECT ModuleObject,
495 IN PUNICODE_STRING ServiceName,
496 IN BOOLEAN FileSystemDriver,
497 OUT PDRIVER_OBJECT *DriverObject);
498
499 NTSTATUS FASTCALL
500 IopAttachFilterDrivers(
501 PDEVICE_NODE DeviceNode,
502 BOOLEAN Lower);
503
504 VOID FASTCALL
505 IopMarkLastReinitializeDriver(VOID);
506
507 VOID FASTCALL
508 IopReinitializeDrivers(VOID);
509
510
511 /* plugplay.c */
512
513 NTSTATUS INIT_FUNCTION
514 IopInitPlugPlayEvents(VOID);
515
516 NTSTATUS
517 IopQueueTargetDeviceEvent(const GUID *Guid,
518 PUNICODE_STRING DeviceIds);
519
520
521 /* pnpmgr.c */
522
523 NTSTATUS
524 IopInitializePnpServices(
525 IN PDEVICE_NODE DeviceNode,
526 IN BOOLEAN BootDrivers);
527
528 NTSTATUS
529 IopInvalidateDeviceRelations(
530 IN PDEVICE_NODE DeviceNode,
531 IN DEVICE_RELATION_TYPE Type);
532
533 /* timer.c */
534 VOID
535 FASTCALL
536 IopInitTimerImplementation(VOID);
537
538 VOID
539 STDCALL
540 IopRemoveTimerFromTimerList(
541 IN PIO_TIMER Timer
542 );
543
544 /* iocomp.c */
545 VOID
546 FASTCALL
547 IopInitIoCompletionImplementation(VOID);
548
549 #define CM_RESOURCE_LIST_SIZE(ResList) \
550 (ResList->Count == 1) ? \
551 FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList. \
552 PartialDescriptors[(ResList)->List[0].PartialResourceList.Count]) \
553 : \
554 FIELD_OFFSET(CM_RESOURCE_LIST, List)
555
556 #endif