ReactOS 0.4.15-dev-7704-gc07eb9f
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)
 
static VOID NTAPI IopFreeApc (IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
 
static 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 528 of file error.c.

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 */
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,
579 if (!LogEntry) return NULL;
580
581 /* Reference the Objects */
584
585 /* Update log size */
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}
#define NULL
Definition: types.h:112
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define InterlockedExchangeAdd
Definition: interlocked.h:181
struct _ERROR_LOG_ENTRY ERROR_LOG_ENTRY
#define IOP_MAXIMUM_LOG_SIZE
Definition: error.c:28
LONG IopTotalLogSize
Definition: error.c:29
Definition: io.h:332
CSHORT Size
Definition: io.h:334
CSHORT Type
Definition: io.h:333
PDEVICE_OBJECT DeviceObject
Definition: io.h:336
PDRIVER_OBJECT DriverObject
Definition: io.h:337
#define TAG_ERROR_LOG
Definition: tag.h:81
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
struct _DRIVER_OBJECT * PDRIVER_OBJECT
#define IO_TYPE_DEVICE
_In_ PVOID IoObject
Definition: iotypes.h:467
#define ERROR_LOG_MAXIMUM_SIZE
Definition: iotypes.h:2042
#define IO_TYPE_ERROR_LOG
#define IO_TYPE_DRIVER
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by ClassInterpretSenseInfo(), ClasspLogSystemEventWithDeviceNumber(), DiskFdoProcessError(), DiskLogCacheInformation(), IopDisassociateThreadIrp(), LibraryLogEvent(), and TiWriteErrorLog().

◆ IoFreeErrorLogEntry()

VOID NTAPI IoFreeErrorLogEntry ( IN PVOID  ElEntry)

Definition at line 604 of file error.c.

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 */
621}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _ERROR_LOG_ENTRY * PERROR_LOG_ENTRY
long LONG
Definition: pedump.c:60
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ 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}
static UNICODE_STRING PortName
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
#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)
@ SecurityIdentification
Definition: lsa.idl:56
VOID NTAPI IopRestartLogWorker(VOID)
Definition: error.c:85
BOOLEAN IopLogPortConnected
Definition: error.c:34
HANDLE IopLogPort
Definition: error.c:35
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103

Referenced by IopLogWorker().

◆ IopFreeApc()

static VOID NTAPI IopFreeApc ( IN PKAPC  Apc,
IN OUT PKNORMAL_ROUTINE NormalRoutine,
IN OUT PVOID NormalContext,
IN OUT PVOID SystemArgument1,
IN OUT PVOID SystemArgument2 
)
static

Definition at line 490 of file error.c.

495{
496 PAGED_CODE();
497
498 /* Free the APC */
500}
#define PAGED_CODE()
#define TAG_APC
Definition: tag.h:79

Referenced by IoRaiseHardError().

◆ IopGetErrorLogEntry()

PLIST_ENTRY NTAPI IopGetErrorLogEntry ( VOID  )

Definition at line 59 of file error.c.

60{
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 */
76 }
77
78 /* Release the lock and return the entry */
80 return ListEntry;
81}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
LIST_ENTRY IopErrorLogListHead
Definition: error.c:30
KSPIN_LOCK IopLogListLock
Definition: error.c:31
BOOLEAN IopLogWorkerRunning
Definition: error.c:33
Definition: typedefs.h:120
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

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}
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI IopLogWorker(IN PVOID Parameter)
Definition: error.c:148
WORK_QUEUE_ITEM IopErrorLogWorkItem
Definition: error.c:36
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190

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 */
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 */
252 if (DriverObject->DriverName.Buffer)
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),
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,
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,
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 */
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,
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 */
481 }
482
483 /* Free the LPC Message */
485}
static VOID ErrorMessage(_In_ DWORD dwErrorCode, _In_opt_ PCWSTR pszMsg,...)
Definition: attrib.c:33
_In_ ULONG _In_ BATTERY_QUERY_INFORMATION_LEVEL _In_ LONG _In_ ULONG _Out_ PULONG ReturnedLength
Definition: batclass.h:188
Definition: bufpool.h:45
static const WCHAR Message[]
Definition: register.c:74
#define PagedPool
Definition: env_spec_w32.h:308
GLfloat GLfloat p
Definition: glext.h:8902
@ Unknown
Definition: i8042prt.h:114
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
NTSYSAPI NTSTATUS NTAPI ZwRequestPort(_In_ HANDLE PortHandle, _In_ PPORT_MESSAGE LpcMessage)
#define PCHAR
Definition: match.c:90
#define min(a, b)
Definition: monoChain.cc:55
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
struct _OBJECT_NAME_INFORMATION * POBJECT_NAME_INFORMATION
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
BOOLEAN NTAPI IopConnectLogPort(VOID)
Definition: error.c:110
PLIST_ENTRY NTAPI IopGetErrorLogEntry(VOID)
Definition: error.c:59
#define IO_ERROR_OBJECT_NAMES_LENGTH
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207
unsigned short USHORT
Definition: pedump.c:61
UNICODE_STRING DriverName
Definition: iotypes.h:2283
LARGE_INTEGER TimeStamp
Definition: io.h:338
LIST_ENTRY ListEntry
Definition: io.h:335
#define TAG_IO
Definition: tag.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define ALIGN_UP_POINTER(ptr, type)
Definition: umtypes.h:97
#define IO_TYPE_ERROR_MESSAGE
#define IO_ERROR_LOG_MESSAGE_LENGTH
Definition: iotypes.h:2038
struct _IO_ERROR_LOG_MESSAGE IO_ERROR_LOG_MESSAGE
struct _IO_ERROR_LOG_PACKET * PIO_ERROR_LOG_PACKET
struct _IO_ERROR_LOG_PACKET IO_ERROR_LOG_PACKET
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by IopLogDpcRoutine(), and IoWriteErrorLogEntry().

◆ IopRaiseHardError()

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

Definition at line 505 of file error.c.

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}
#define UNIMPLEMENTED
Definition: debug.h:115
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

Referenced by IoRaiseHardError().

◆ IopRestartLogWorker()

VOID NTAPI IopRestartLogWorker ( VOID  )

Definition at line 85 of file error.c.

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

Referenced by IopConnectLogPort(), and IopLogWorker().

◆ IoRaiseHardError()

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

Definition at line 664 of file error.c.

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,
697 NULL,
700 Irp);
701
703}
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define KernelMode
Definition: asm.h:34
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
static VOID NTAPI IopRaiseHardError(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: error.c:505
BOOLEAN NTAPI KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost)
Definition: apc.c:735
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
KTHREAD Tcb
Definition: pstypes.h:1103
ULONG HardErrorsAreDisabled
Definition: pstypes.h:1183
Definition: ketypes.h:547
_In_opt_ PVPB _In_ PDEVICE_OBJECT RealDeviceObject
Definition: iofuncs.h:1504
#define IO_NO_INCREMENT
Definition: iotypes.h:598

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

◆ IoRaiseInformationalHardError()

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

Definition at line 710 of file error.c.

713{
714 DPRINT1("IoRaiseInformationalHardError: %lx, '%wZ'\n", ErrorStatus, String);
715#if DBG
716 ASSERT(ErrorStatus != STATUS_FILE_CORRUPT_ERROR); /* CORE-17587 */
717#endif
718 return FALSE;
719}
#define DPRINT1
Definition: precomp.h:8
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433

Referenced by mount_vol().

◆ IoSetThreadHardErrorMode()

BOOLEAN NTAPI IoSetThreadHardErrorMode ( IN BOOLEAN  HardErrorEnabled)

Definition at line 726 of file error.c.

727{
729 BOOLEAN OldMode;
730
731 /* Get the current value */
732 OldMode = !Thread->HardErrorsAreDisabled;
733
734 /* Set the new one and return the old */
735 Thread->HardErrorsAreDisabled = !HardErrorEnabled;
736 return OldMode;
737}
unsigned char BOOLEAN
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81

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

◆ IoWriteErrorLogEntry()

VOID NTAPI IoWriteErrorLogEntry ( IN PVOID  ElEntry)

Definition at line 628 of file error.c.

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 */
648 {
649 /* It's not, initialize it and queue it */
653 }
654
655 /* Release the lock and return */
657}
_Out_ PKIRQL Irql
Definition: csq.h:179
#define InsertHeadList(ListHead, Entry)
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570

Referenced by ClassInterpretSenseInfo(), ClasspLogSystemEventWithDeviceNumber(), DiskFdoProcessError(), DiskLogCacheInformation(), IopDisassociateThreadIrp(), LibraryLogEvent(), 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().