reactos/ntoskrnl/io/iomgr/error.c

673 lines
21 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/io/error.c
* PURPOSE: I/O Error Functions and Error Log Support
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* TYPES *********************************************************************/
typedef struct _IOP_ERROR_LOG_WORKER_DPC
{
KDPC Dpc;
KTIMER Timer;
} IOP_ERROR_LOG_WORKER_DPC, *PIOP_ERROR_LOG_WORKER_DPC;
/* GLOBALS *******************************************************************/
LONG IopTotalLogSize;
LIST_ENTRY IopErrorLogListHead;
KSPIN_LOCK IopLogListLock;
BOOLEAN IopLogWorkerRunning;
BOOLEAN IopLogPortConnected;
HANDLE IopLogPort;
WORK_QUEUE_ITEM IopErrorLogWorkItem;
PDEVICE_OBJECT IopErrorLogObject;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
IopLogDpcRoutine(IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
/* If we have a DPC, free it */
if (Dpc) ExFreePool(Dpc);
/* Initialize and queue the work item */
ExInitializeWorkItem(&IopErrorLogWorkItem, IopLogWorker, NULL);
ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue);
}
PLIST_ENTRY
NTAPI
IopGetErrorLogEntry(VOID)
{
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
/* Acquire the lock and check if the list is empty */
KeAcquireSpinLock(&IopLogListLock, &OldIrql);
if (IsListEmpty(&IopErrorLogListHead))
{
/* List is empty, disable the worker and return NULL */
IopLogWorkerRunning = FALSE;
ListEntry = NULL;
}
else
{
/* Otherwise, remove an entry */
ListEntry = RemoveHeadList(&IopErrorLogListHead);
}
/* Release the lock and return the entry */
KeReleaseSpinLock(&IopLogListLock, OldIrql);
return ListEntry;
}
VOID
NTAPI
IopRestartLogWorker(VOID)
{
PIOP_ERROR_LOG_WORKER_DPC WorkerDpc;
LARGE_INTEGER Timeout;
/* Allocate a DPC Context */
WorkerDpc = ExAllocatePool(NonPagedPool, sizeof(IOP_ERROR_LOG_WORKER_DPC));
if (!WorkerDpc)
{
/* Fail */
IopLogWorkerRunning = FALSE;
return;
}
/* Initialize DPC and Timer */
KeInitializeDpc(&WorkerDpc->Dpc, IopLogDpcRoutine, WorkerDpc);
KeInitializeTimer(&WorkerDpc->Timer);
/* Restart after 30 seconds */
Timeout.QuadPart = (LONGLONG)-300000000;
KeSetTimer(&WorkerDpc->Timer, Timeout, &WorkerDpc->Dpc);
}
BOOLEAN
NTAPI
IopConnectLogPort(VOID)
{
UNICODE_STRING PortName = RTL_CONSTANT_STRING(L"\\ErrorLogPort");
NTSTATUS Status;
/* Make sure we're not already connected */
if (IopLogPortConnected) return TRUE;
/* Connect the port */
Status = ZwConnectPort(&IopLogPort,
&PortName,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
if (NT_SUCCESS(Status))
{
/* Remember we're connected */
IopLogPortConnected = TRUE;
return TRUE;
}
/* We failed, try again */
IopRestartLogWorker();
return FALSE;
}
VOID
NTAPI
IopLogWorker(IN PVOID Parameter)
{
PELF_API_MSG Message;
PIO_ERROR_LOG_MESSAGE ErrorMessage;
PLIST_ENTRY ListEntry;
PERROR_LOG_ENTRY LogEntry;
PIO_ERROR_LOG_PACKET Packet;
PCHAR StringBuffer;
ULONG RemainingLength;
PDRIVER_OBJECT DriverObject;
ULONG DriverNameLength = 0, DeviceNameLength;
UNICODE_STRING DriverNameString;
NTSTATUS Status;
UCHAR Buffer[256];
POBJECT_NAME_INFORMATION ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
POBJECT_NAME_INFORMATION PoolObjectNameInfo = NULL;
ULONG ReturnedLength, MessageLength;
PWCHAR p;
ULONG ExtraStringLength;
PAGED_CODE();
/* Connect to the port */
if (!IopConnectLogPort()) return;
/* Allocate the message */
Message = ExAllocatePool(PagedPool, IO_ERROR_LOG_MESSAGE_LENGTH);
if (!Message)
{
/* Couldn't allocate, try again */
IopRestartLogWorker();
return;
}
/* Copy the message */
RtlZeroMemory(Message, sizeof(ELF_API_MSG));
/* Get the actual I/O Structure */
ErrorMessage = &Message->IoErrorMessage;
/* Start loop */
while (TRUE)
{
/* Get an entry */
ListEntry = IopGetErrorLogEntry();
if (!ListEntry) break;
LogEntry = CONTAINING_RECORD(ListEntry, ERROR_LOG_ENTRY, ListEntry);
/* Get pointer to the log packet */
Packet = (PIO_ERROR_LOG_PACKET)((ULONG_PTR)LogEntry +
sizeof(ERROR_LOG_ENTRY));
/* Calculate the total length of the message only */
MessageLength = sizeof(IO_ERROR_LOG_MESSAGE) -
sizeof(ERROR_LOG_ENTRY) -
sizeof(IO_ERROR_LOG_PACKET) +
LogEntry->Size;
/* Copy the packet */
RtlCopyMemory(&ErrorMessage->EntryData,
Packet,
LogEntry->Size - sizeof(ERROR_LOG_ENTRY));
/* Set the timestamp and time */
ErrorMessage->TimeStamp = LogEntry->TimeStamp;
ErrorMessage->Type = IO_TYPE_ERROR_MESSAGE;
/* Check if this message has any strings */
if (Packet->NumberOfStrings)
{
/* String buffer is after the current strings */
StringBuffer = (PCHAR)&ErrorMessage->EntryData +
Packet->StringOffset;
}
else
{
/* Otherwise, string buffer is at the end */
StringBuffer = (PCHAR)ErrorMessage + MessageLength;
}
/* Align the buffer */
StringBuffer = ALIGN_UP_POINTER(StringBuffer, WCHAR);
/* Set the offset for the driver's name to the current buffer */
ErrorMessage->DriverNameOffset = (ULONG_PTR)(StringBuffer -
(ULONG_PTR)ErrorMessage);
/* Check how much space we have left for the device string */
RemainingLength = (ULONG)((ULONG_PTR)Message +
IO_ERROR_LOG_MESSAGE_LENGTH -
(ULONG_PTR)StringBuffer);
/* Now check if there is a driver object */
DriverObject = LogEntry->DriverObject;
if (DriverObject)
{
/* Check if the driver has a name */
if (DriverObject->DriverName.Buffer)
{
/* Use its name */
DriverNameString.Buffer = DriverObject->DriverName.Buffer;
DriverNameLength = DriverObject->DriverName.Length;
}
else
DriverNameString.Buffer = NULL;
/* Check if there isn't a valid name*/
if (!DriverNameLength)
{
/* Query the name directly */
Status = ObQueryNameString(DriverObject,
ObjectNameInfo,
sizeof(Buffer),
&ReturnedLength);
if (!(NT_SUCCESS(Status)) || !(ObjectNameInfo->Name.Length))
{
/* We don't have a name */
DriverNameLength = 0;
}
}
}
else
{
/* Use default name */
DriverNameString.Buffer = L"Application Popup";
DriverNameLength = wcslen(DriverNameString.Buffer) * sizeof(WCHAR);
}
/* Check if we have a driver name by here */
if (DriverNameLength)
{
/* Skip to the end of the driver's name */
p = &DriverNameString.Buffer[DriverNameLength / sizeof(WCHAR)];
/* Now we'll walk backwards and assume the minimum size */
DriverNameLength = sizeof(WCHAR);
p--;
while ((*p != L'\\') && (p != DriverNameString.Buffer))
{
/* No backslash found, keep going */
p--;
DriverNameLength += sizeof(WCHAR);
}
/* Now we probably hit the backslash itself, skip past it */
if (*p == L'\\')
{
p++;
DriverNameLength -= sizeof(WCHAR);
}
/*
* Now make sure that the driver name fits in our buffer, minus 3
* NULL chars, and copy the name in our string buffer
*/
DriverNameLength = min(DriverNameLength,
RemainingLength - 3 * sizeof(UNICODE_NULL));
RtlCopyMemory(StringBuffer, p, DriverNameLength);
}
/* Null-terminate the driver name */
*((PWSTR)(StringBuffer + DriverNameLength)) = L'\0';
DriverNameLength += sizeof(WCHAR);
/* Go to the next string buffer position */
StringBuffer += DriverNameLength;
RemainingLength -= DriverNameLength;
/* Update the string offset and check if we have a device object */
ErrorMessage->EntryData.StringOffset = (USHORT)
((ULONG_PTR)StringBuffer -
(ULONG_PTR)ErrorMessage);
if (LogEntry->DeviceObject)
{
/* We do, query its name */
Status = ObQueryNameString(LogEntry->DeviceObject,
ObjectNameInfo,
sizeof(OBJECT_NAME_INFORMATION) +
100 -
DriverNameLength,
&ReturnedLength);
if ((!NT_SUCCESS(Status)) || !(ObjectNameInfo->Name.Length))
{
/* Setup an empty name */
ObjectNameInfo->Name.Length = 0;
ObjectNameInfo->Name.Buffer = L"";
/* Check if we failed because our buffer wasn't large enough */
if (Status == STATUS_INFO_LENGTH_MISMATCH)
{
/* Then we'll allocate one... we really want this name! */
PoolObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
ReturnedLength,
TAG_IO);
if (PoolObjectNameInfo)
{
/* Query it again */
ObjectNameInfo = PoolObjectNameInfo;
Status = ObQueryNameString(LogEntry->DeviceObject,
ObjectNameInfo,
ReturnedLength,
&ReturnedLength);
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;
UNIMPLEMENTED;
/* 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 running */
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;
}
/*
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
* @implemented
*/
BOOLEAN
NTAPI
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
{
PETHREAD Thread = PsGetCurrentThread();
BOOLEAN OldMode;
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
/* Get the current value */
OldMode = !Thread->HardErrorsAreDisabled;
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
/* Set the new one and return the old */
Thread->HardErrorsAreDisabled = !HardErrorEnabled;
return OldMode;
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
}