ReactOS  0.4.14-dev-98-gb0d4763
error.c File Reference
#include <ntoskrnl.h>
#include <subsys/iolog/iolog.h>
#include <debug.h>
Include dependency graph for error.c:

Go to the source code of this file.

Classes

struct  _IOP_ERROR_LOG_WORKER_DPC
 

Macros

#define NDEBUG
 
#define IOP_MAXIMUM_LOG_SIZE   (100 * PAGE_SIZE)
 
#define IO_ERROR_OBJECT_NAMES_LENGTH   100
 

Typedefs

typedef struct _IOP_ERROR_LOG_WORKER_DPC IOP_ERROR_LOG_WORKER_DPC
 
typedef struct _IOP_ERROR_LOG_WORKER_DPCPIOP_ERROR_LOG_WORKER_DPC
 

Functions

VOID NTAPI IopLogDpcRoutine (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
PLIST_ENTRY NTAPI IopGetErrorLogEntry (VOID)
 
VOID NTAPI IopRestartLogWorker (VOID)
 
BOOLEAN NTAPI IopConnectLogPort (VOID)
 
VOID NTAPI IopLogWorker (IN PVOID Parameter)
 
VOID NTAPI IopFreeApc (IN PKAPC Apc)
 
VOID NTAPI IopRaiseHardError (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
PVOID NTAPI IoAllocateErrorLogEntry (IN PVOID IoObject, IN UCHAR EntrySize)
 
VOID NTAPI IoFreeErrorLogEntry (IN PVOID ElEntry)
 
VOID NTAPI IoWriteErrorLogEntry (IN PVOID ElEntry)
 
VOID NTAPI IoRaiseHardError (IN PIRP Irp, IN PVPB Vpb, IN PDEVICE_OBJECT RealDeviceObject)
 
BOOLEAN NTAPI IoRaiseInformationalHardError (IN NTSTATUS ErrorStatus, IN PUNICODE_STRING String, IN PKTHREAD Thread)
 
BOOLEAN NTAPI IoSetThreadHardErrorMode (IN BOOLEAN HardErrorEnabled)
 

Variables

LONG IopTotalLogSize
 
LIST_ENTRY IopErrorLogListHead
 
KSPIN_LOCK IopLogListLock
 
BOOLEAN IopLogWorkerRunning
 
BOOLEAN IopLogPortConnected
 
HANDLE IopLogPort
 
WORK_QUEUE_ITEM IopErrorLogWorkItem
 
PDEVICE_OBJECT IopErrorLogObject
 

Macro Definition Documentation

◆ IO_ERROR_OBJECT_NAMES_LENGTH

#define IO_ERROR_OBJECT_NAMES_LENGTH   100

◆ IOP_MAXIMUM_LOG_SIZE

#define IOP_MAXIMUM_LOG_SIZE   (100 * PAGE_SIZE)

Definition at line 28 of file error.c.

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file error.c.

Typedef Documentation

◆ IOP_ERROR_LOG_WORKER_DPC

◆ PIOP_ERROR_LOG_WORKER_DPC

Function Documentation

◆ IoAllocateErrorLogEntry()

PVOID NTAPI IoAllocateErrorLogEntry ( IN PVOID  IoObject,
IN UCHAR  EntrySize 
)

Definition at line 520 of file error.c.

522 {
523  PERROR_LOG_ENTRY LogEntry;
524  ULONG LogEntrySize;
527 
528  /* Make sure we have an object */
529  if (!IoObject) return NULL;
530 
531  /* Check if this is a device object or driver object */
533  if (DeviceObject->Type == IO_TYPE_DEVICE)
534  {
535  /* It's a device, get the driver */
536  // DeviceObject = (PDEVICE_OBJECT)IoObject;
537  DriverObject = DeviceObject->DriverObject;
538  }
539  else if (DeviceObject->Type == IO_TYPE_DRIVER)
540  {
541  /* It's a driver, so we don't have a device */
542  DeviceObject = NULL;
544  }
545  else
546  {
547  /* Fail */
548  return NULL;
549  }
550 
551  /* Check whether the size is too small or too large */
552  if ((EntrySize < sizeof(IO_ERROR_LOG_PACKET)) ||
554  {
555  /* Fail */
556  return NULL;
557  }
558 
559  /* Round up the size and calculate the total size */
560  EntrySize = ROUND_UP(EntrySize, sizeof(PVOID));
561  LogEntrySize = sizeof(ERROR_LOG_ENTRY) + EntrySize;
562 
563  /* Check if we're past our buffer */
564  // TODO: Improve (what happens in case of concurrent calls?)
565  if (IopTotalLogSize + LogEntrySize > IOP_MAXIMUM_LOG_SIZE) return NULL;
566 
567  /* Allocate the entry */
569  LogEntrySize,
570  TAG_ERROR_LOG);
571  if (!LogEntry) return NULL;
572 
573  /* Reference the Objects */
576 
577  /* Update log size */
578  InterlockedExchangeAdd(&IopTotalLogSize, LogEntrySize);
579 
580  /* Clear the entry and set it up */
581  RtlZeroMemory(LogEntry, LogEntrySize);
582  LogEntry->Type = IO_TYPE_ERROR_LOG;
583  LogEntry->Size = LogEntrySize;
584  LogEntry->DeviceObject = DeviceObject;
585  LogEntry->DriverObject = DriverObject;
586 
587  /* Return the entry data */
588  return (PVOID)((ULONG_PTR)LogEntry + sizeof(ERROR_LOG_ENTRY));
589 }
LONG IopTotalLogSize
Definition: error.c:29
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
struct _ERROR_LOG_ENTRY ERROR_LOG_ENTRY
struct _DEVICE_OBJECT * PDEVICE_OBJECT
PDEVICE_OBJECT DeviceObject
Definition: io.h:332
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
CSHORT Size
Definition: io.h:330
#define IOP_MAXIMUM_LOG_SIZE
Definition: error.c:28
CSHORT Type
Definition: io.h:329
#define IO_TYPE_DEVICE
smooth NULL
Definition: ftsmooth.c:416
#define ERROR_LOG_MAXIMUM_SIZE
Definition: iotypes.h:1999
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define IO_TYPE_ERROR_LOG
#define TAG_ERROR_LOG
Definition: tag.h:70
_In_ PVOID IoObject
Definition: iotypes.h:435
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: io.h:327
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define IO_TYPE_DRIVER
PDRIVER_OBJECT DriverObject
Definition: io.h:333
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
struct _DRIVER_OBJECT * PDRIVER_OBJECT

Referenced by ClassInterpretSenseInfo(), ClassNotifyFailurePredicted(), DisableWriteCache(), DiskSetCacheInformation(), IopDisassociateThreadIrp(), ScsiClassInterpretSenseInfo(), and TiWriteErrorLog().

◆ IoFreeErrorLogEntry()

VOID NTAPI IoFreeErrorLogEntry ( IN PVOID  ElEntry)

Definition at line 596 of file error.c.

597 {
598  PERROR_LOG_ENTRY LogEntry;
599 
600  /* Make sure there is an entry */
601  if (!ElEntry) return;
602 
603  /* Get the actual header */
604  LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY));
605 
606  /* Dereference both objects */
607  if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
608  if (LogEntry->DriverObject) ObDereferenceObject(LogEntry->DriverObject);
609 
610  /* Decrease the total allocation size and free the entry */
612  ExFreePoolWithTag(LogEntry, TAG_ERROR_LOG);
613 }
LONG IopTotalLogSize
Definition: error.c:29
struct _ERROR_LOG_ENTRY ERROR_LOG_ENTRY
struct _ERROR_LOG_ENTRY * PERROR_LOG_ENTRY
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
PDEVICE_OBJECT DeviceObject
Definition: io.h:332
uint32_t ULONG_PTR
Definition: typedefs.h:63
CSHORT Size
Definition: io.h:330
long LONG
Definition: pedump.c:60
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define TAG_ERROR_LOG
Definition: tag.h:70
Definition: io.h:327
PDRIVER_OBJECT DriverObject
Definition: io.h:333
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

◆ IopConnectLogPort()

BOOLEAN NTAPI IopConnectLogPort ( VOID  )

Definition at line 110 of file error.c.

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 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
smooth NULL
Definition: ftsmooth.c:416
#define ELF_PORT_NAME
Definition: iolog.h:15
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 NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103
Status
Definition: gdiplustypes.h:24
HANDLE IopLogPort
Definition: error.c:35
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
VOID NTAPI IopRestartLogWorker(VOID)
Definition: error.c:85
BOOLEAN IopLogPortConnected
Definition: error.c:34
IN PUNICODE_STRING PortName
Definition: conport.c:35
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IopLogWorker().

◆ IopFreeApc()

VOID NTAPI IopFreeApc ( IN PKAPC  Apc)

Definition at line 489 of file error.c.

490 {
491  /* Free the APC */
492  ExFreePool(Apc);
493 }
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by IoRaiseHardError().

◆ IopGetErrorLogEntry()

PLIST_ENTRY NTAPI IopGetErrorLogEntry ( VOID  )

Definition at line 59 of file error.c.

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 }
LIST_ENTRY IopErrorLogListHead
Definition: error.c:30
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
BOOLEAN IopLogWorkerRunning
Definition: error.c:33
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: typedefs.h:117
KSPIN_LOCK IopLogListLock
Definition: error.c:31
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627

Referenced by IopLogWorker().

◆ IopLogDpcRoutine()

VOID NTAPI IopLogDpcRoutine ( IN PKDPC  Dpc,
IN PVOID  DeferredContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)

Definition at line 44 of file error.c.

48 {
49  /* If we have a DPC, free it */
50  if (Dpc) ExFreePool(Dpc);
51 
52  /* Initialize and queue the work item */
55 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
WORK_QUEUE_ITEM IopErrorLogWorkItem
Definition: error.c:36
VOID NTAPI IopLogWorker(IN PVOID Parameter)
Definition: error.c:148
smooth NULL
Definition: ftsmooth.c:416
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by IopRestartLogWorker().

◆ IopLogWorker()

VOID NTAPI IopLogWorker ( IN PVOID  Parameter)

Definition at line 148 of file error.c.

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 }
signed char * PCHAR
Definition: retypes.h:7
static ULONG(WINAPI *pRtlNtStatusToDosError)(NTSTATUS Status)
LONG IopTotalLogSize
Definition: error.c:29
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#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 UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
struct _ERROR_LOG_ENTRY ERROR_LOG_ENTRY
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
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
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
PDEVICE_OBJECT DeviceObject
Definition: io.h:332
uint16_t * PWCHAR
Definition: typedefs.h:54
_In_ PVOID Parameter
Definition: ldrtypes.h:241
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
CSHORT Size
Definition: io.h:330
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
struct _IO_ERROR_LOG_PACKET IO_ERROR_LOG_PACKET
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
Definition: bufpool.h:45
#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
VOID ErrorMessage(DWORD dwErrorCode, LPTSTR szFormat,...)
Definition: error.c:26
NTSYSAPI NTSTATUS NTAPI ZwRequestPort(_In_ HANDLE PortHandle, _In_ PPORT_MESSAGE LpcMessage)
#define IO_TYPE_ERROR_MESSAGE
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _IO_ERROR_LOG_MESSAGE IO_ERROR_LOG_MESSAGE
#define TAG_ERROR_LOG
Definition: tag.h:70
CHAR Message[80]
Definition: alive.c:5
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
Definition: io.h:327
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:187
Definition: typedefs.h:117
LARGE_INTEGER TimeStamp
Definition: io.h:334
Status
Definition: gdiplustypes.h:24
HANDLE IopLogPort
Definition: error.c:35
#define IO_ERROR_OBJECT_NAMES_LENGTH
LIST_ENTRY ListEntry
Definition: io.h:331
unsigned short USHORT
Definition: pedump.c:61
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
KSPIN_LOCK IopLogListLock
Definition: error.c:31
#define ALIGN_UP_POINTER(ptr, type)
Definition: umtypes.h:97
#define min(a, b)
Definition: monoChain.cc:55
PDRIVER_OBJECT DriverObject
Definition: io.h:333
struct _IO_ERROR_LOG_PACKET * PIO_ERROR_LOG_PACKET
VOID NTAPI IopRestartLogWorker(VOID)
Definition: error.c:85
#define IO_ERROR_LOG_MESSAGE_LENGTH
Definition: iotypes.h:1995
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOLEAN IopLogPortConnected
Definition: error.c:34
#define ULONG_PTR
Definition: config.h:101
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
UNICODE_STRING DriverName
Definition: iotypes.h:2175
struct _OBJECT_NAME_INFORMATION * POBJECT_NAME_INFORMATION

Referenced by IopLogDpcRoutine(), and IoWriteErrorLogEntry().

◆ IopRaiseHardError()

VOID NTAPI IopRaiseHardError ( IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)

Definition at line 497 of file error.c.

500 {
501  PIRP Irp = NormalContext;
502  //PVPB Vpb = SystemArgument1;
503  //PDEVICE_OBJECT DeviceObject = SystemArgument2;
504 
506 
507  /* FIXME: UNIMPLEMENTED */
508  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
509  Irp->IoStatus.Information = 0;
511 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
_In_ PIRP Irp
Definition: csq.h:116
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define IoCompleteRequest
Definition: irp.c:1240
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by IoRaiseHardError().

◆ IopRestartLogWorker()

VOID NTAPI IopRestartLogWorker ( VOID  )

Definition at line 85 of file error.c.

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 }
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
VOID NTAPI IopLogDpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: error.c:44
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
int64_t LONGLONG
Definition: typedefs.h:66
BOOLEAN IopLogWorkerRunning
Definition: error.c:33
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
static ULONG Timeout
Definition: ping.c:61
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711

Referenced by IopConnectLogPort(), and IopLogWorker().

◆ IoRaiseHardError()

VOID NTAPI IoRaiseHardError ( IN PIRP  Irp,
IN PVPB  Vpb,
IN PDEVICE_OBJECT  RealDeviceObject 
)

Definition at line 656 of file error.c.

659 {
660  PETHREAD Thread = (PETHREAD)&Irp->Tail.Overlay.Thread;
661  PKAPC ErrorApc;
662 
663  /* Don't do anything if hard errors are disabled on the thread */
665  {
666  /* Complete the request */
667  Irp->IoStatus.Information = 0;
669  return;
670  }
671 
672  /* Setup an APC */
674  sizeof(KAPC),
675  TAG_APC);
676  KeInitializeApc(ErrorApc,
677  &Thread->Tcb,
678  Irp->ApcEnvironment,
679  NULL,
680  IopFreeApc,
682  KernelMode,
683  Irp);
684 
685  /* Queue an APC to deal with the error (see osr documentation) */
686  KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, 0);
687 }
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
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI IopFreeApc(IN PKAPC Apc)
Definition: error.c:489
KTHREAD Tcb
Definition: pstypes.h:1034
VOID NTAPI IopRaiseHardError(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: error.c:497
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define TAG_APC
Definition: tag.h:68
if(!(yy_init))
Definition: macro.lex.yy.c:714
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_In_opt_ PVPB _In_ PDEVICE_OBJECT RealDeviceObject
Definition: iofuncs.h:1499
Definition: ketypes.h:535
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
ULONG HardErrorsAreDisabled
Definition: pstypes.h:1114
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1664

Referenced by _Requires_lock_held_(), Ext2ExceptionHandler(), FFSExceptionHandler(), RfsdExceptionHandler(), and UDFExceptionHandler().

◆ IoRaiseInformationalHardError()

BOOLEAN NTAPI IoRaiseInformationalHardError ( IN NTSTATUS  ErrorStatus,
IN PUNICODE_STRING  String,
IN PKTHREAD  Thread 
)

Definition at line 694 of file error.c.

697 {
698  DPRINT1("IoRaiseInformationalHardError: %lx, '%wZ'\n", ErrorStatus, String);
699  return FALSE;
700 }
static WCHAR String[]
Definition: stringtable.c:55
#define DPRINT1
Definition: precomp.h:8

Referenced by mount_vol().

◆ IoSetThreadHardErrorMode()

BOOLEAN NTAPI IoSetThreadHardErrorMode ( IN BOOLEAN  HardErrorEnabled)

Definition at line 707 of file error.c.

708 {
710  BOOLEAN OldMode;
711 
712  /* Get the current value */
713  OldMode = !Thread->HardErrorsAreDisabled;
714 
715  /* Set the new one and return the old */
716  Thread->HardErrorsAreDisabled = !HardErrorEnabled;
717  return OldMode;
718 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
unsigned char BOOLEAN
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ULONG HardErrorsAreDisabled
Definition: pstypes.h:1114

Referenced by FsRtlGetFileSize(), ObKillProcess(), OpenRemoteDatabase(), ReconcileThisDatabaseWithMasterWorker(), and TestHardError().

◆ IoWriteErrorLogEntry()

VOID NTAPI IoWriteErrorLogEntry ( IN PVOID  ElEntry)

Definition at line 620 of file error.c.

621 {
622  PERROR_LOG_ENTRY LogEntry;
623  KIRQL Irql;
624 
625  /* Make sure there is an entry */
626  if (!ElEntry) return;
627 
628  /* Get the actual header */
629  LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY));
630 
631  /* Get time stamp */
632  KeQuerySystemTime(&LogEntry->TimeStamp);
633 
634  /* Acquire the lock and insert this write in the list */
637 
638  /* Check if the worker is running */
639  if (!IopLogWorkerRunning)
640  {
641  /* It's not, initialize it and queue it */
645  }
646 
647  /* Release the lock and return */
649 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define TRUE
Definition: types.h:120
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
struct _ERROR_LOG_ENTRY ERROR_LOG_ENTRY
WORK_QUEUE_ITEM IopErrorLogWorkItem
Definition: error.c:36
struct _ERROR_LOG_ENTRY * PERROR_LOG_ENTRY
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LIST_ENTRY IopErrorLogListHead
Definition: error.c:30
VOID NTAPI IopLogWorker(IN PVOID Parameter)
Definition: error.c:148
_Out_ PKIRQL Irql
Definition: csq.h:179
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
BOOLEAN IopLogWorkerRunning
Definition: error.c:33
Definition: io.h:327
LARGE_INTEGER TimeStamp
Definition: io.h:334
LIST_ENTRY ListEntry
Definition: io.h:331
KSPIN_LOCK IopLogListLock
Definition: error.c:31
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627

Referenced by ClassInterpretSenseInfo(), ClassNotifyFailurePredicted(), DisableWriteCache(), DiskSetCacheInformation(), IopDisassociateThreadIrp(), ScsiClassInterpretSenseInfo(), and TiWriteErrorLog().

Variable Documentation

◆ IopErrorLogListHead

LIST_ENTRY IopErrorLogListHead

Definition at line 30 of file error.c.

Referenced by IoInitSystem(), IopGetErrorLogEntry(), IopLogWorker(), and IoWriteErrorLogEntry().

◆ IopErrorLogObject

PDEVICE_OBJECT IopErrorLogObject

Definition at line 38 of file error.c.

Referenced by IopMarkBootPartition().

◆ IopErrorLogWorkItem

WORK_QUEUE_ITEM IopErrorLogWorkItem

Definition at line 36 of file error.c.

Referenced by IopLogDpcRoutine(), and IoWriteErrorLogEntry().

◆ IopLogListLock

KSPIN_LOCK IopLogListLock

Definition at line 31 of file error.c.

Referenced by IoInitSystem(), IopGetErrorLogEntry(), IopLogWorker(), and IoWriteErrorLogEntry().

◆ IopLogPort

HANDLE IopLogPort

Definition at line 35 of file error.c.

Referenced by IopConnectLogPort(), and IopLogWorker().

◆ IopLogPortConnected

BOOLEAN IopLogPortConnected

Definition at line 34 of file error.c.

Referenced by IopConnectLogPort(), and IopLogWorker().

◆ IopLogWorkerRunning

BOOLEAN IopLogWorkerRunning

Definition at line 33 of file error.c.

Referenced by IopGetErrorLogEntry(), IopRestartLogWorker(), and IoWriteErrorLogEntry().

◆ IopTotalLogSize

LONG IopTotalLogSize

Definition at line 29 of file error.c.

Referenced by IoAllocateErrorLogEntry(), IoFreeErrorLogEntry(), and IopLogWorker().