ReactOS  0.4.15-dev-1200-gc3b3fcd
error.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/io/iomgr/error.c
5  * PURPOSE: I/O Error Functions and Error Log Support
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Eric Kohl
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include <ntoskrnl.h>
13 #include <subsys/iolog/iolog.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 /* TYPES *********************************************************************/
19 
21 {
25 
26 /* GLOBALS *******************************************************************/
27 
28 #define IOP_MAXIMUM_LOG_SIZE (100 * PAGE_SIZE)
32 
37 
39 
40 /* PRIVATE FUNCTIONS *********************************************************/
41 
42 VOID
43 NTAPI
48 {
49  /* If we have a DPC, free it */
50  if (Dpc) ExFreePool(Dpc);
51 
52  /* Initialize and queue the work item */
55 }
56 
58 NTAPI
60 {
61  KIRQL OldIrql;
62  PLIST_ENTRY ListEntry;
63 
64  /* Acquire the lock and check if the list is empty */
67  {
68  /* List is empty, disable the worker and return NULL */
70  ListEntry = NULL;
71  }
72  else
73  {
74  /* Otherwise, remove an entry */
75  ListEntry = RemoveHeadList(&IopErrorLogListHead);
76  }
77 
78  /* Release the lock and return the entry */
80  return ListEntry;
81 }
82 
83 VOID
84 NTAPI
86 {
87  PIOP_ERROR_LOG_WORKER_DPC WorkerDpc;
89 
90  /* Allocate a DPC Context */
92  if (!WorkerDpc)
93  {
94  /* Fail */
96  return;
97  }
98 
99  /* Initialize DPC and Timer */
100  KeInitializeDpc(&WorkerDpc->Dpc, IopLogDpcRoutine, WorkerDpc);
101  KeInitializeTimer(&WorkerDpc->Timer);
102 
103  /* Restart after 30 seconds */
104  Timeout.QuadPart = (LONGLONG)-300000000;
105  KeSetTimer(&WorkerDpc->Timer, Timeout, &WorkerDpc->Dpc);
106 }
107 
108 BOOLEAN
109 NTAPI
111 {
114  SECURITY_QUALITY_OF_SERVICE SecurityQos;
115 
116  /* Make sure we're not already connected */
117  if (IopLogPortConnected) return TRUE;
118 
119  /* Setup the QoS structure */
120  SecurityQos.Length = sizeof(SecurityQos);
123  SecurityQos.EffectiveOnly = TRUE;
124 
125  /* Connect the port */
127  &PortName,
128  &SecurityQos,
129  NULL,
130  NULL,
131  NULL,
132  NULL,
133  NULL);
134  if (NT_SUCCESS(Status))
135  {
136  /* Remember we're connected */
138  return TRUE;
139  }
140 
141  /* We failed, try again */
143  return FALSE;
144 }
145 
146 VOID
147 NTAPI
149 {
150 #define IO_ERROR_OBJECT_NAMES_LENGTH 100
151 
155  PLIST_ENTRY ListEntry;
156  PERROR_LOG_ENTRY LogEntry;
159  ULONG RemainingLength;
161  PWCHAR NameString;
162  ULONG DriverNameLength, DeviceNameLength;
165  POBJECT_NAME_INFORMATION PoolObjectNameInfo;
166  ULONG ReturnedLength, MessageLength;
167  ULONG ExtraStringLength;
168  PWCHAR p;
169 
170  PAGED_CODE();
171 
173 
174  /* Connect to the port */
175  if (!IopConnectLogPort()) return;
176 
177  /* Allocate the message */
179  if (!Message)
180  {
181  /* Couldn't allocate, try again */
183  return;
184  }
185 
186  /* Zero out the message and get the actual I/O structure */
187  RtlZeroMemory(Message, sizeof(*Message));
188  ErrorMessage = &Message->IoErrorMessage;
189 
190  /* Start loop */
191  while (TRUE)
192  {
193  /* Get an entry */
194  ListEntry = IopGetErrorLogEntry();
195  if (!ListEntry) break;
196  LogEntry = CONTAINING_RECORD(ListEntry, ERROR_LOG_ENTRY, ListEntry);
197 
198  /* Get pointer to the log packet */
199  Packet = (PIO_ERROR_LOG_PACKET)((ULONG_PTR)LogEntry +
200  sizeof(ERROR_LOG_ENTRY));
201 
202  /* Calculate the total length of the message only */
203  MessageLength = sizeof(IO_ERROR_LOG_MESSAGE) -
204  sizeof(ERROR_LOG_ENTRY) -
205  sizeof(IO_ERROR_LOG_PACKET) +
206  LogEntry->Size;
207 
208  /* Copy the packet */
209  RtlCopyMemory(&ErrorMessage->EntryData,
210  Packet,
211  LogEntry->Size - sizeof(ERROR_LOG_ENTRY));
212 
213  /* Set the timestamp and time */
214  ErrorMessage->TimeStamp = LogEntry->TimeStamp;
216 
217  /* Check if this message has any strings */
218  if (Packet->NumberOfStrings)
219  {
220  /* String buffer is after the current strings */
221  StringBuffer = (PCHAR)&ErrorMessage->EntryData +
222  Packet->StringOffset;
223  }
224  else
225  {
226  /* Otherwise, string buffer is at the end */
227  StringBuffer = (PCHAR)ErrorMessage + MessageLength;
228  }
229 
230  /* Align the buffer */
232 
233  /* Set the offset for the driver's name to the current buffer */
234  ErrorMessage->DriverNameOffset = (ULONG)(StringBuffer -
236 
237  /* Check how much space we have left for the device string */
238  RemainingLength = (ULONG)((ULONG_PTR)Message +
241 
242  NameString = NULL;
243  DriverNameLength = 0; DeviceNameLength = 0;
244  PoolObjectNameInfo = NULL;
245  ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
246 
247  /* Now check if there is a driver object */
248  DriverObject = LogEntry->DriverObject;
249  if (DriverObject)
250  {
251  /* Check if the driver has a name, and use it if so */
253  {
254  NameString = DriverObject->DriverName.Buffer;
255  DriverNameLength = DriverObject->DriverName.Length;
256  }
257  else
258  {
259  NameString = NULL;
260  DriverNameLength = 0;
261  }
262 
263  /* Check if there isn't a valid name */
264  if (!DriverNameLength)
265  {
266  /* Query the name directly */
268  ObjectNameInfo,
269  sizeof(Buffer),
270  &ReturnedLength);
271  if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0))
272  {
273  /* We don't have a name */
274  DriverNameLength = 0;
275  }
276  else
277  {
278  NameString = ObjectNameInfo->Name.Buffer;
279  DriverNameLength = ObjectNameInfo->Name.Length;
280  }
281  }
282  }
283  else
284  {
285  /* Use default name */
286  NameString = L"Application Popup";
287  DriverNameLength = (ULONG)wcslen(NameString) * sizeof(WCHAR);
288  }
289 
290  /* Check if we have a driver name */
291  if (DriverNameLength)
292  {
293  /* Skip to the end of the driver's name */
294  p = &NameString[DriverNameLength / sizeof(WCHAR)];
295 
296  /* Now we'll walk backwards and assume the minimum size */
297  DriverNameLength = sizeof(WCHAR);
298  p--;
299  while ((*p != L'\\') && (p != NameString))
300  {
301  /* No backslash found, keep going */
302  p--;
303  DriverNameLength += sizeof(WCHAR);
304  }
305 
306  /* Now we probably hit the backslash itself, skip past it */
307  if (*p == L'\\')
308  {
309  p++;
310  DriverNameLength -= sizeof(WCHAR);
311  }
312 
313  /*
314  * Now make sure that the driver name fits in the buffer, minus
315  * 3 NULL chars (driver name, device name, and remaining strings),
316  * and copy the driver name in the string buffer.
317  */
318  DriverNameLength = min(DriverNameLength,
319  RemainingLength - 3 * sizeof(UNICODE_NULL));
320  RtlCopyMemory(StringBuffer, p, DriverNameLength);
321  }
322 
323  /* Null-terminate the driver name */
324  *((PWSTR)(StringBuffer + DriverNameLength)) = UNICODE_NULL;
325  DriverNameLength += sizeof(WCHAR);
326 
327  /* Go to the next string buffer position */
328  StringBuffer += DriverNameLength;
329  RemainingLength -= DriverNameLength;
330 
331  /* Update the string offset */
332  ErrorMessage->EntryData.StringOffset =
334 
335  /* Check if we have a device object */
336  if (LogEntry->DeviceObject)
337  {
338  /* We do, query its name */
340  ObjectNameInfo,
341  sizeof(Buffer) - DriverNameLength,
342  &ReturnedLength);
343  if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0))
344  {
345  /* Setup an empty name */
346  RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, L"", 0);
347 
348  /* Check if we failed because our buffer wasn't large enough */
350  {
351  /* Then we'll allocate one... we really want this name! */
352  PoolObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
354  TAG_IO);
355  if (PoolObjectNameInfo)
356  {
357  /* Query it again */
358  ObjectNameInfo = PoolObjectNameInfo;
360  ObjectNameInfo,
362  &ReturnedLength);
363  if (NT_SUCCESS(Status))
364  {
365  /* Success, update the information */
366  ObjectNameInfo->Name.Length =
367  IO_ERROR_OBJECT_NAMES_LENGTH - (USHORT)DriverNameLength;
368  }
369  }
370  }
371  }
372 
373  NameString = ObjectNameInfo->Name.Buffer;
374  DeviceNameLength = ObjectNameInfo->Name.Length;
375  }
376  else
377  {
378  /* No device object, setup an empty name */
379  NameString = L"";
380  DeviceNameLength = 0;
381  }
382 
383  /*
384  * Now make sure that the device name fits in the buffer, minus
385  * 2 NULL chars (device name, and remaining strings), and copy
386  * the device name in the string buffer.
387  */
388  DeviceNameLength = min(DeviceNameLength,
389  RemainingLength - 2 * sizeof(UNICODE_NULL));
390  RtlCopyMemory(StringBuffer, NameString, DeviceNameLength);
391 
392  /* Null-terminate the device name */
393  *((PWSTR)(StringBuffer + DeviceNameLength)) = UNICODE_NULL;
394  DeviceNameLength += sizeof(WCHAR);
395 
396  /* Free the buffer if we had one */
397  if (PoolObjectNameInfo)
398  {
399  ExFreePoolWithTag(PoolObjectNameInfo, TAG_IO);
400  PoolObjectNameInfo = NULL;
401  }
402 
403  /* Go to the next string buffer position */
404  ErrorMessage->EntryData.NumberOfStrings++;
405  StringBuffer += DeviceNameLength;
406  RemainingLength -= DeviceNameLength;
407 
408  /* Check if we have any extra strings */
409  if (Packet->NumberOfStrings)
410  {
411  /* Find out the size of the extra strings */
412  ExtraStringLength = LogEntry->Size -
413  sizeof(ERROR_LOG_ENTRY) -
414  Packet->StringOffset;
415 
416  /* Round up the length */
417  ExtraStringLength = ROUND_UP(ExtraStringLength, sizeof(WCHAR));
418 
419  /* Make sure that the extra strings fit in our buffer */
420  if (ExtraStringLength > (RemainingLength - sizeof(UNICODE_NULL)))
421  {
422  /* They wouldn't, so set normalize the length */
423  MessageLength -= ExtraStringLength - RemainingLength;
424  ExtraStringLength = RemainingLength - sizeof(UNICODE_NULL);
425  }
426 
427  /* Now copy the extra strings */
429  (PCHAR)Packet + Packet->StringOffset,
430  ExtraStringLength);
431 
432  /* Null-terminate them */
433  *((PWSTR)(StringBuffer + ExtraStringLength)) = UNICODE_NULL;
434  }
435 
436  /* Set the driver name length */
437  ErrorMessage->DriverNameLength = (USHORT)DriverNameLength;
438 
439  /* Update the message length to include the driver and device names */
440  MessageLength += DriverNameLength + DeviceNameLength;
441  ErrorMessage->Size = (USHORT)MessageLength;
442 
443  /* Now update it again for the size of the actual LPC */
444  MessageLength += (FIELD_OFFSET(ELF_API_MSG, IoErrorMessage) -
446 
447  /* Set the total and data lengths */
448  Message->Header.u1.s1.TotalLength =
449  (USHORT)(sizeof(PORT_MESSAGE) + MessageLength);
450  Message->Header.u1.s1.DataLength = (USHORT)MessageLength;
451 
452  /* Send the message */
453  Status = ZwRequestPort(IopLogPort, &Message->Header);
454  if (!NT_SUCCESS(Status))
455  {
456  /*
457  * An error happened while sending the message on the port.
458  * Close the port, requeue the log message on top of the list
459  * and restart the worker.
460  */
463 
465  &LogEntry->ListEntry,
466  &IopLogListLock);
467 
469  break;
470  }
471 
472  /* NOTE: The following is basically 'IoFreeErrorLogEntry(Packet)' */
473 
474  /* Dereference both objects */
475  if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
476  if (LogEntry->DriverObject) ObDereferenceObject(LogEntry->DriverObject);
477 
478  /* Decrease the total allocation size and free the entry */
480  ExFreePoolWithTag(LogEntry, TAG_ERROR_LOG);
481  }
482 
483  /* Free the LPC Message */
485 }
486 
487 static
488 VOID
489 NTAPI
491  IN OUT PKNORMAL_ROUTINE* NormalRoutine,
492  IN OUT PVOID* NormalContext,
495 {
496  PAGED_CODE();
497 
498  /* Free the APC */
500 }
501 
502 static
503 VOID
504 NTAPI
505 IopRaiseHardError(IN PVOID NormalContext,
508 {
509  PIRP Irp = NormalContext;
510  //PVPB Vpb = SystemArgument1;
511  //PDEVICE_OBJECT DeviceObject = SystemArgument2;
512 
514 
515  /* FIXME: UNIMPLEMENTED */
516  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
517  Irp->IoStatus.Information = 0;
519 }
520 
521 /* PUBLIC FUNCTIONS **********************************************************/
522 
523 /*
524  * @implemented
525  */
526 PVOID
527 NTAPI
530 {
531  PERROR_LOG_ENTRY LogEntry;
532  ULONG LogEntrySize;
535 
536  /* Make sure we have an object */
537  if (!IoObject) return NULL;
538 
539  /* Check if this is a device object or driver object */
541  if (DeviceObject->Type == IO_TYPE_DEVICE)
542  {
543  /* It's a device, get the driver */
544  // DeviceObject = (PDEVICE_OBJECT)IoObject;
545  DriverObject = DeviceObject->DriverObject;
546  }
547  else if (DeviceObject->Type == IO_TYPE_DRIVER)
548  {
549  /* It's a driver, so we don't have a device */
550  DeviceObject = NULL;
552  }
553  else
554  {
555  /* Fail */
556  return NULL;
557  }
558 
559  /* Check whether the size is too small or too large */
560  if ((EntrySize < sizeof(IO_ERROR_LOG_PACKET)) ||
562  {
563  /* Fail */
564  return NULL;
565  }
566 
567  /* Round up the size and calculate the total size */
568  EntrySize = ROUND_UP(EntrySize, sizeof(PVOID));
569  LogEntrySize = sizeof(ERROR_LOG_ENTRY) + EntrySize;
570 
571  /* Check if we're past our buffer */
572  // TODO: Improve (what happens in case of concurrent calls?)
573  if (IopTotalLogSize + LogEntrySize > IOP_MAXIMUM_LOG_SIZE) return NULL;
574 
575  /* Allocate the entry */
577  LogEntrySize,
578  TAG_ERROR_LOG);
579  if (!LogEntry) return NULL;
580 
581  /* Reference the Objects */
584 
585  /* Update log size */
586  InterlockedExchangeAdd(&IopTotalLogSize, LogEntrySize);
587 
588  /* Clear the entry and set it up */
589  RtlZeroMemory(LogEntry, LogEntrySize);
590  LogEntry->Type = IO_TYPE_ERROR_LOG;
591  LogEntry->Size = LogEntrySize;
592  LogEntry->DeviceObject = DeviceObject;
593  LogEntry->DriverObject = DriverObject;
594 
595  /* Return the entry data */
596  return (PVOID)((ULONG_PTR)LogEntry + sizeof(ERROR_LOG_ENTRY));
597 }
598 
599 /*
600  * @implemented
601  */
602 VOID
603 NTAPI
605 {
606  PERROR_LOG_ENTRY LogEntry;
607 
608  /* Make sure there is an entry */
609  if (!ElEntry) return;
610 
611  /* Get the actual header */
612  LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY));
613 
614  /* Dereference both objects */
615  if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
616  if (LogEntry->DriverObject) ObDereferenceObject(LogEntry->DriverObject);
617 
618  /* Decrease the total allocation size and free the entry */
620  ExFreePoolWithTag(LogEntry, TAG_ERROR_LOG);
621 }
622 
623 /*
624  * @implemented
625  */
626 VOID
627 NTAPI
629 {
630  PERROR_LOG_ENTRY LogEntry;
631  KIRQL Irql;
632 
633  /* Make sure there is an entry */
634  if (!ElEntry) return;
635 
636  /* Get the actual header */
637  LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY));
638 
639  /* Get time stamp */
640  KeQuerySystemTime(&LogEntry->TimeStamp);
641 
642  /* Acquire the lock and insert this write in the list */
645 
646  /* Check if the worker is running */
647  if (!IopLogWorkerRunning)
648  {
649  /* It's not, initialize it and queue it */
653  }
654 
655  /* Release the lock and return */
657 }
658 
659 /*
660  * @implemented
661  */
662 VOID
663 NTAPI
665  IN PVPB Vpb,
667 {
668  PETHREAD Thread = Irp->Tail.Overlay.Thread;
669  PKAPC ErrorApc;
670 
671  /* Don't do anything if hard errors are disabled on the thread */
673  {
674  /* Complete the request */
675  Irp->IoStatus.Information = 0;
677  return;
678  }
679 
680  // TODO: In case we were called in the context of a paging I/O or for
681  // a synchronous operation, that happens with APCs disabled, queue the
682  // hard-error call for later processing (see also IofCompleteRequest).
683 
684  /* Setup an APC and queue it to deal with the error (see OSR documentation) */
685  ErrorApc = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ErrorApc), TAG_APC);
686  if (!ErrorApc)
687  {
688  /* Fail */
690  return;
691  }
692 
693  KeInitializeApc(ErrorApc,
694  &Thread->Tcb,
695  Irp->ApcEnvironment,
696  IopFreeApc,
697  NULL,
699  KernelMode,
700  Irp);
701 
703 }
704 
705 /*
706  * @unimplemented
707  */
708 BOOLEAN
709 NTAPI
713 {
714  DPRINT1("IoRaiseInformationalHardError: %lx, '%wZ'\n", ErrorStatus, String);
715  return FALSE;
716 }
717 
718 /*
719  * @implemented
720  */
721 BOOLEAN
722 NTAPI
724 {
726  BOOLEAN OldMode;
727 
728  /* Get the current value */
729  OldMode = !Thread->HardErrorsAreDisabled;
730 
731  /* Set the new one and return the old */
732  Thread->HardErrorsAreDisabled = !HardErrorEnabled;
733  return OldMode;
734 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
VOID NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine, IN KPROCESSOR_MODE Mode, IN PVOID Context)
Definition: apc.c:651
signed char * PCHAR
Definition: retypes.h:7
static ULONG(WINAPI *pRtlNtStatusToDosError)(NTSTATUS Status)
LONG IopTotalLogSize
Definition: error.c:29
#define IN
Definition: typedefs.h:39
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define TAG_IO
Definition: tag.h:69
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
BOOLEAN NTAPI IopConnectLogPort(VOID)
Definition: error.c:110
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
struct _IOP_ERROR_LOG_WORKER_DPC * PIOP_ERROR_LOG_WORKER_DPC
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
struct _ERROR_LOG_ENTRY ERROR_LOG_ENTRY
struct _DEVICE_OBJECT * PDEVICE_OBJECT
WORK_QUEUE_ITEM IopErrorLogWorkItem
Definition: error.c:36
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
struct _ERROR_LOG_ENTRY * PERROR_LOG_ENTRY
uint16_t * PWSTR
Definition: typedefs.h:56
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LONG NTSTATUS
Definition: precomp.h:26
KTHREAD Tcb
Definition: pstypes.h:1045
LIST_ENTRY IopErrorLogListHead
Definition: error.c:30
PLIST_ENTRY NTAPI IopGetErrorLogEntry(VOID)
Definition: error.c:59
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1209
static VOID NTAPI IopFreeApc(IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
Definition: error.c:490
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
static WCHAR String[]
Definition: stringtable.c:55
PDEVICE_OBJECT DeviceObject
Definition: io.h:332
uint16_t * PWCHAR
Definition: typedefs.h:56
_In_ PVOID Parameter
Definition: ldrtypes.h:241
VOID NTAPI IopLogWorker(IN PVOID Parameter)
Definition: error.c:148
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
_Out_ PKIRQL Irql
Definition: csq.h:179
VOID NTAPI IopLogDpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: error.c:44
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:628
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
uint32_t ULONG_PTR
Definition: typedefs.h:65
CSHORT Size
Definition: io.h:330
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI IoFreeErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:604
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define IOP_MAXIMUM_LOG_SIZE
Definition: error.c:28
long LONG
Definition: pedump.c:60
CSHORT Type
Definition: io.h:329
#define IO_TYPE_DEVICE
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
VOID ErrorMessage(IN DWORD dwErrorCode, IN PCTSTR szFormat OPTIONAL,...)
Definition: error.c:26
smooth NULL
Definition: ftsmooth.c:416
struct _IO_ERROR_LOG_PACKET IO_ERROR_LOG_PACKET
#define ERROR_LOG_MAXIMUM_SIZE
Definition: iotypes.h:2022
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
Definition: bufpool.h:45
#define ELF_PORT_NAME
Definition: iolog.h:15
#define TAG_APC
Definition: tag.h:68
#define InterlockedExchangeAdd
Definition: interlocked.h:181
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define PCHAR
Definition: match.c:90
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:528
#define IO_TYPE_ERROR_LOG
NTSYSAPI NTSTATUS NTAPI ZwRequestPort(_In_ HANDLE PortHandle, _In_ PPORT_MESSAGE LpcMessage)
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
int64_t LONGLONG
Definition: typedefs.h:68
NTSYSAPI NTSTATUS NTAPI ZwConnectPort(_Out_ PHANDLE PortHandle, _In_ PUNICODE_STRING PortName, _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, _In_opt_ PPORT_VIEW ClientView, _In_opt_ PREMOTE_PORT_VIEW ServerView, _In_opt_ PULONG MaxMessageLength, _In_opt_ PVOID ConnectionInformation, _In_opt_ PULONG ConnectionInformationLength)
#define IO_TYPE_ERROR_MESSAGE
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:511
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _IO_ERROR_LOG_MESSAGE IO_ERROR_LOG_MESSAGE
BOOLEAN NTAPI IoRaiseInformationalHardError(IN NTSTATUS ErrorStatus, IN PUNICODE_STRING String, IN PKTHREAD Thread)
Definition: error.c:710
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
BOOLEAN IopLogWorkerRunning
Definition: error.c:33
#define TAG_ERROR_LOG
Definition: tag.h:70
_In_ PVOID IoObject
Definition: iotypes.h:450
static VOID NTAPI IopRaiseHardError(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: error.c:505
CHAR Message[80]
Definition: alive.c:5
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_In_opt_ PVPB _In_ PDEVICE_OBJECT RealDeviceObject
Definition: iofuncs.h:1499
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
Definition: io.h:327
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: ketypes.h:687
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:723
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
Definition: ketypes.h:535
Definition: typedefs.h:119
LARGE_INTEGER TimeStamp
Definition: io.h:334
PDEVICE_OBJECT IopErrorLogObject
Definition: error.c:38
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
HANDLE IopLogPort
Definition: error.c:35
#define IO_ERROR_OBJECT_NAMES_LENGTH
LIST_ENTRY ListEntry
Definition: io.h:331
static ULONG Timeout
Definition: ping.c:61
struct _IOP_ERROR_LOG_WORKER_DPC IOP_ERROR_LOG_WORKER_DPC
unsigned short USHORT
Definition: pedump.c:61
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
KSPIN_LOCK IopLogListLock
Definition: error.c:31
#define ALIGN_UP_POINTER(ptr, type)
Definition: umtypes.h:97
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define min(a, b)
Definition: monoChain.cc:55
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
#define IO_TYPE_DRIVER
PDRIVER_OBJECT DriverObject
Definition: io.h:333
#define DPRINT1
Definition: precomp.h:8
struct _IO_ERROR_LOG_PACKET * PIO_ERROR_LOG_PACKET
VOID NTAPI IopRestartLogWorker(VOID)
Definition: error.c:85
Definition: iotypes.h:168
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
#define IO_ERROR_LOG_MESSAGE_LENGTH
Definition: iotypes.h:2018
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
BOOLEAN IopLogPortConnected
Definition: error.c:34
VOID NTAPI IoRaiseHardError(IN PIRP Irp, IN PVPB Vpb, IN PDEVICE_OBJECT RealDeviceObject)
Definition: error.c:664
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:632
GLfloat GLfloat p
Definition: glext.h:8902
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
ULONG HardErrorsAreDisabled
Definition: pstypes.h:1125
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
struct _DRIVER_OBJECT * PDRIVER_OBJECT
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1673
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
UNICODE_STRING DriverName
Definition: iotypes.h:2263
struct _OBJECT_NAME_INFORMATION * POBJECT_NAME_INFORMATION
IN PUNICODE_STRING PortName
Definition: conport.c:35
#define PAGED_CODE()
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675