📄 error.c
字号:
if (NT_SUCCESS(Status))
{
/* Success, update the information */
ObjectNameInfo->Name.Length =
100 - (USHORT)DriverNameLength;
}
}
}
}
}
else
{
/* No device object, setup an empty name */
ObjectNameInfo->Name.Length = 0;
ObjectNameInfo->Name.Buffer = L"";
}
/*
* Now make sure that the device name fits in our buffer, minus 2
* NULL chars, and copy the name in our string buffer
*/
DeviceNameLength = min(ObjectNameInfo->Name.Length,
RemainingLength - 2 * sizeof(UNICODE_NULL));
RtlCopyMemory(StringBuffer,
ObjectNameInfo->Name.Buffer,
DeviceNameLength);
/* Null-terminate the device name */
*((PWSTR)(StringBuffer + DeviceNameLength)) = L'\0';
DeviceNameLength += sizeof(WCHAR);
/* Free the buffer if we had one */
if (PoolObjectNameInfo) ExFreePool(PoolObjectNameInfo);
/* Go to the next string buffer position */
ErrorMessage->EntryData.NumberOfStrings++;
StringBuffer += DeviceNameLength;
RemainingLength -= DeviceNameLength;
/* Check if we have any extra strings */
if (Packet->NumberOfStrings)
{
/* Find out the size of the extra strings */
ExtraStringLength = LogEntry->Size -
sizeof(ERROR_LOG_ENTRY) -
Packet->StringOffset;
/* Make sure that the extra strings fit in our buffer */
if (ExtraStringLength > (RemainingLength - sizeof(UNICODE_NULL)))
{
/* They wouldn't, so set normalize the length */
MessageLength -= ExtraStringLength - RemainingLength;
ExtraStringLength = RemainingLength - sizeof(UNICODE_NULL);
}
/* Now copy the extra strings */
RtlCopyMemory(StringBuffer,
(PCHAR)Packet + Packet->StringOffset,
ExtraStringLength);
/* Null-terminate them */
*((PWSTR)(StringBuffer + ExtraStringLength)) = L'\0';
}
/* Set the driver name length */
ErrorMessage->DriverNameLength = (USHORT)DriverNameLength;
/* Update the message length to include the device and driver names */
MessageLength += DeviceNameLength + DriverNameLength;
ErrorMessage->Size = (USHORT)MessageLength;
/* Now update it again, internally, for the size of the actual LPC */
MessageLength += (FIELD_OFFSET(ELF_API_MSG, IoErrorMessage) -
FIELD_OFFSET(ELF_API_MSG, Unknown[0]));
/* Set the total and data lengths */
Message->h.u1.s1.TotalLength = (USHORT)(sizeof(PORT_MESSAGE) +
MessageLength);
Message->h.u1.s1.DataLength = (USHORT)(MessageLength);
/* Send the message */
Status = NtRequestPort(IopLogPort, (PPORT_MESSAGE)Message);
if (!NT_SUCCESS(Status))
{
/* Requeue log message and restart the worker */
ExInterlockedInsertTailList(&IopErrorLogListHead,
&LogEntry->ListEntry,
&IopLogListLock);
IopLogWorkerRunning = FALSE;
IopRestartLogWorker();
break;
}
/* Derefernece the device object */
if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
if (DriverObject) ObDereferenceObject(LogEntry->DriverObject);
/* Update size */
InterlockedExchangeAdd(&IopTotalLogSize,
-(LONG)(LogEntry->Size -
sizeof(ERROR_LOG_ENTRY)));
}
/* Free the LPC Message */
ExFreePool(Message);
}
VOID
NTAPI
IopFreeApc(IN PKAPC Apc,
IN PKNORMAL_ROUTINE *NormalRoutine,
IN PVOID *NormalContext,
IN PVOID *SystemArgument1,
IN PVOID *SystemArgument2)
{
/* Free the APC */
ExFreePool(Apc);
}
VOID
NTAPI
IopRaiseHardError(IN PKAPC Apc,
IN PKNORMAL_ROUTINE *NormalRoutine,
IN PVOID *NormalContext,
IN PVOID *SystemArgument1,
IN PVOID *SystemArgument2)
{
PIRP Irp = (PIRP)NormalContext;
//PVPB Vpb = (PVPB)SystemArgument1;
//PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)SystemArgument2;
/* FIXME: UNIMPLEMENTED */
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
}
/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
PVOID
NTAPI
IoAllocateErrorLogEntry(IN PVOID IoObject,
IN UCHAR EntrySize)
{
PERROR_LOG_ENTRY LogEntry;
ULONG LogEntrySize;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
/* Make sure we have an object */
if (!IoObject) return NULL;
/* Check if we're past our buffer */
if (IopTotalLogSize > PAGE_SIZE) return NULL;
/* Calculate the total size and allocate it */
LogEntrySize = sizeof(ERROR_LOG_ENTRY) + EntrySize;
LogEntry = ExAllocatePoolWithTag(NonPagedPool,
LogEntrySize,
TAG_ERROR_LOG);
if (!LogEntry) return NULL;
/* Check if this is a device object or driver object */
if (((PDEVICE_OBJECT)IoObject)->Type == IO_TYPE_DEVICE)
{
/* It's a device, get the driver */
DeviceObject = (PDEVICE_OBJECT)IoObject;
DriverObject = DeviceObject->DriverObject;
}
else if (((PDEVICE_OBJECT)IoObject)->Type == IO_TYPE_DRIVER)
{
/* It's a driver, so we don' thave a device */
DeviceObject = NULL;
DriverObject = IoObject;
}
else
{
/* Fail */
return NULL;
}
/* Reference the Objects */
if (DeviceObject) ObReferenceObject(DeviceObject);
if (DriverObject) ObReferenceObject(DriverObject);
/* Update log size */
InterlockedExchangeAdd(&IopTotalLogSize, EntrySize);
/* Clear the entry and set it up */
RtlZeroMemory(LogEntry, EntrySize);
LogEntry->Type = IO_TYPE_ERROR_LOG;
LogEntry->Size = EntrySize;
LogEntry->DeviceObject = DeviceObject;
LogEntry->DriverObject = DriverObject;
/* Return the entry data */
return (PVOID)((ULONG_PTR)LogEntry + sizeof(ERROR_LOG_ENTRY));
}
/*
* @implemented
*/
VOID
NTAPI
IoFreeErrorLogEntry(IN PVOID ElEntry)
{
PERROR_LOG_ENTRY LogEntry;
/* Make sure there's an entry */
if (!ElEntry) return;
/* Get the actual header */
LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY));
/* Dereference both objects */
if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
if (LogEntry->DriverObject) ObDereferenceObject(LogEntry->DriverObject);
/* Decrease total allocation size and free the entry */
InterlockedExchangeAdd(&IopTotalLogSize,
-(LONG)(LogEntry->Size - sizeof(ERROR_LOG_ENTRY)));
ExFreePool(LogEntry);
}
/*
* @implemented
*/
VOID
NTAPI
IoWriteErrorLogEntry(IN PVOID ElEntry)
{
PERROR_LOG_ENTRY LogEntry;
KIRQL Irql;
/* Get the main header */
LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry -
sizeof(ERROR_LOG_ENTRY));
/* Get time stamp */
KeQuerySystemTime(&LogEntry->TimeStamp);
/* Acquire the lock and insert this write in the list */
KeAcquireSpinLock(&IopLogListLock, &Irql);
InsertHeadList(&IopErrorLogListHead, &LogEntry->ListEntry);
/* Check if the worker is runnign */
if (!IopLogWorkerRunning)
{
#if 0
/* It's not, initialize it and queue it */
ExInitializeWorkItem(&IopErrorLogWorkItem,
IopLogWorker,
&IopErrorLogWorkItem);
ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue);
IopLogWorkerRunning = TRUE;
#endif
}
/* Release the lock and return */
KeReleaseSpinLock(&IopLogListLock, Irql);
}
/*
* @implemented
*/
VOID
NTAPI
IoRaiseHardError(IN PIRP Irp,
IN PVPB Vpb,
IN PDEVICE_OBJECT RealDeviceObject)
{
PETHREAD Thread = (PETHREAD)&Irp->Tail.Overlay.Thread;
PKAPC ErrorApc;
/* Don't do anything if hard errors are disabled on the thread */
if (Thread->HardErrorsAreDisabled)
{
/* Complete the request */
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return;
}
/* Setup an APC */
ErrorApc = ExAllocatePoolWithTag(NonPagedPool,
sizeof(KAPC),
TAG_APC);
KeInitializeApc(ErrorApc,
&Thread->Tcb,
Irp->ApcEnvironment,
NULL,
(PKRUNDOWN_ROUTINE)IopFreeApc,
(PKNORMAL_ROUTINE)IopRaiseHardError,
KernelMode,
Irp);
/* Queue an APC to deal with the error (see osr documentation) */
KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, 0);
}
/*
* @unimplemented
*/
BOOLEAN
NTAPI
IoRaiseInformationalHardError(IN NTSTATUS ErrorStatus,
IN PUNICODE_STRING String,
IN PKTHREAD Thread)
{
UNIMPLEMENTED;
return(FALSE);
}
/*
* @implemented
*/
BOOLEAN
NTAPI
IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
{
PETHREAD Thread = PsGetCurrentThread();
BOOLEAN Old;
/* Get the current value */
Old = !Thread->HardErrorsAreDisabled;
/* Set the new one and return the old */
Thread->HardErrorsAreDisabled = !HardErrorEnabled;
return Old;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -