ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
July 2006
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
19 participants
662 discussions
Start a n
N
ew thread
[ion] 22735: [FORMATTING] - Fix STDCALL->NTAPI and some other commenting/formatting issues. [AUDIT] - File doesn't even have a function over 3 lines long, no reason to lock it.
by ion@svn.reactos.org
Author: ion Date: Sat Jul 1 07:45:00 2006 New Revision: 22735 URL:
http://svn.reactos.org/svn/reactos?rev=22735&view=rev
Log: [FORMATTING] - Fix STDCALL->NTAPI and some other commenting/formatting issues. [AUDIT] - File doesn't even have a function over 3 lines long, no reason to lock it. Modified: trunk/reactos/ntoskrnl/io/util.c (contents, props changed) Modified: trunk/reactos/ntoskrnl/io/util.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/util.c?rev=227…
============================================================================== --- trunk/reactos/ntoskrnl/io/util.c (original) +++ trunk/reactos/ntoskrnl/io/util.c Sat Jul 1 07:45:00 2006 @@ -22,30 +22,34 @@ * @implemented */ VOID -STDCALL +NTAPI IoAcquireCancelSpinLock(PKIRQL Irql) { - KeAcquireSpinLock(&CancelSpinLock,Irql); + /* Just acquire the internal lock */ + KeAcquireSpinLock(&CancelSpinLock,Irql); } /* * @implemented */ PVOID -STDCALL +NTAPI IoGetInitialStack(VOID) { - return(PsGetCurrentThread()->Tcb.InitialStack); + /* Return the initial stack from the TCB */ + return PsGetCurrentThread()->Tcb.InitialStack; } /* * @implemented */ VOID -STDCALL +NTAPI IoGetStackLimits(OUT PULONG LowLimit, OUT PULONG HighLimit) { + /* Return the limits from the TEB... this is wrong! */ + DPRINT1("FIXME: IoGetStackLimits returning B*LLSHIT!\n"); *LowLimit = (ULONG)NtCurrentTeb()->Tib.StackLimit; *HighLimit = (ULONG)NtCurrentTeb()->Tib.StackBase; } @@ -54,7 +58,7 @@ * @implemented */ BOOLEAN -STDCALL +NTAPI IoIsSystemThread(IN PETHREAD Thread) { /* Call the Ps Function */ @@ -64,96 +68,93 @@ /* * @implemented */ -BOOLEAN STDCALL +BOOLEAN +NTAPI IoIsWdmVersionAvailable(IN UCHAR MajorVersion, IN UCHAR MinorVersion) { - /* MinorVersion = 0x20 : WinXP - 0x10 : Win2k - 0x5 : WinMe - <0x5 : Win98 - - We report Win2k now - */ - if (MajorVersion <= 1 && MinorVersion <= 0x10) - return TRUE; - return FALSE; + /* Return support for WDM 1.10 (Windows 2000) */ + if (MajorVersion <= 1 && MinorVersion <= 0x10) return TRUE; + return FALSE; } /* * @implemented */ VOID -STDCALL +NTAPI IoReleaseCancelSpinLock(KIRQL Irql) { - KeReleaseSpinLock(&CancelSpinLock,Irql); + /* Release the internal lock */ + KeReleaseSpinLock(&CancelSpinLock,Irql); } /* * @implemented */ PEPROCESS -STDCALL +NTAPI IoThreadToProcess(IN PETHREAD Thread) { - return(Thread->ThreadsProcess); + /* Return the thread's process */ + return Thread->ThreadsProcess; } /* * @implemented */ -NTSTATUS STDCALL +NTSTATUS +NTAPI IoCheckDesiredAccess(IN OUT PACCESS_MASK DesiredAccess, - IN ACCESS_MASK GrantedAccess) + IN ACCESS_MASK GrantedAccess) { - PAGED_CODE(); + PAGED_CODE(); - RtlMapGenericMask(DesiredAccess, - &IoFileObjectType->TypeInfo.GenericMapping); + /* Map the generic mask */ + RtlMapGenericMask(DesiredAccess, + &IoFileObjectType->TypeInfo.GenericMapping); - if ((~(*DesiredAccess) & GrantedAccess) != 0) - return STATUS_ACCESS_DENIED; - else + /* Fail if the access masks don't grant full access */ + if ((~(*DesiredAccess) & GrantedAccess)) return STATUS_ACCESS_DENIED; return STATUS_SUCCESS; -} - - -/* - * @unimplemented - */ -NTSTATUS STDCALL -IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, - IN ULONG EaLength, - OUT PULONG ErrorOffset) -{ - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); -} - - -/* - * @unimplemented - */ -NTSTATUS STDCALL -IoCheckFunctionAccess(IN ACCESS_MASK GrantedAccess, - IN UCHAR MajorFunction, - IN UCHAR MinorFunction, - IN ULONG IoControlCode, - IN PVOID ExtraData OPTIONAL, - IN PVOID ExtraData2 OPTIONAL) -{ - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); } /* * @unimplemented */ NTSTATUS -STDCALL -IoValidateDeviceIoControlAccess(IN PIRP Irp, - IN ULONG RequiredAccess) +NTAPI +IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, + IN ULONG EaLength, + OUT PULONG ErrorOffset) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +IoCheckFunctionAccess(IN ACCESS_MASK GrantedAccess, + IN UCHAR MajorFunction, + IN UCHAR MinorFunction, + IN ULONG IoControlCode, + IN PVOID ExtraData OPTIONAL, + IN PVOID ExtraData2 OPTIONAL) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +IoValidateDeviceIoControlAccess(IN PIRP Irp, + IN ULONG RequiredAccess) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; @@ -162,37 +163,36 @@ /* * @implemented */ -VOID STDCALL +VOID +NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, - IN PDEVICE_OBJECT DeviceObject) + IN PDEVICE_OBJECT DeviceObject) { - Thread->DeviceToVerify = DeviceObject; -} - - -/* - * @implemented - */ -VOID STDCALL -IoSetHardErrorOrVerifyDevice(IN PIRP Irp, - IN PDEVICE_OBJECT DeviceObject) -{ - Irp->Tail.Overlay.Thread->DeviceToVerify = DeviceObject; + /* Set the pointer in the thread */ + Thread->DeviceToVerify = DeviceObject; } /* * @implemented */ -PDEVICE_OBJECT STDCALL -IoGetDeviceToVerify(IN PETHREAD Thread) -/* - * FUNCTION: Returns a pointer to the device, representing a removable-media - * device, that is the target of the given thread's I/O request - */ +VOID +NTAPI +IoSetHardErrorOrVerifyDevice(IN PIRP Irp, + IN PDEVICE_OBJECT DeviceObject) { - return(Thread->DeviceToVerify); + /* Set the pointer in the IRP */ + Irp->Tail.Overlay.Thread->DeviceToVerify = DeviceObject; } - +/* + * @implemented + */ +PDEVICE_OBJECT +NTAPI +IoGetDeviceToVerify(IN PETHREAD Thread) +{ + /* Return the pointer that was set with IoSetDeviceToVerify */ + return Thread->DeviceToVerify; +} /* EOF */ Propchange: trunk/reactos/ntoskrnl/io/util.c ------------------------------------------------------------------------------ --- svn:needs-lock (original) +++ svn:needs-lock (removed) @@ -1,1 +1,0 @@ -*
18 years, 5 months
1
0
0
0
[ion] 22734: - Add some missing IO_ERROR definitions to the DDK and add some tags - Fix IoSetThreadHardErrorMode... it was reading the TEB instead of the PETHREAD. - Optimize Error Logging: Use a static work item instead of allocating one each time, and don't use a spinlock for the buffer count, when we can use interlocked functions instead. - Log Entries can have Device AND/OR Driver Objects, not just a single one. They must also be referenced/dereferenced on allocation/free. - Rewrite IopLogWo
by ion@svn.reactos.org
Author: ion Date: Sat Jul 1 07:36:15 2006 New Revision: 22734 URL:
http://svn.reactos.org/svn/reactos?rev=22734&view=rev
Log: - Add some missing IO_ERROR definitions to the DDK and add some tags - Fix IoSetThreadHardErrorMode... it was reading the TEB instead of the PETHREAD. - Optimize Error Logging: Use a static work item instead of allocating one each time, and don't use a spinlock for the buffer count, when we can use interlocked functions instead. - Log Entries can have Device AND/OR Driver Objects, not just a single one. They must also be referenced/dereferenced on allocation/free. - Rewrite IopLogWorker to properly deal with Device/Driver objects and querying their names, as well as with additional strings that the caller might be sending. Modified: trunk/reactos/include/ddk/winddk.h trunk/reactos/ntoskrnl/include/internal/io.h trunk/reactos/ntoskrnl/include/internal/tag.h trunk/reactos/ntoskrnl/io/error.c Modified: trunk/reactos/include/ddk/winddk.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=2…
============================================================================== --- trunk/reactos/include/ddk/winddk.h (original) +++ trunk/reactos/include/ddk/winddk.h Sat Jul 1 07:36:15 2006 @@ -1849,6 +1849,14 @@ #define IO_ERROR_LOG_MESSAGE_HEADER_LENGTH (sizeof(IO_ERROR_LOG_MESSAGE) - \ sizeof(IO_ERROR_LOG_PACKET) + \ (sizeof(WCHAR) * 40)) +#define ERROR_LOG_MESSAGE_LIMIT_SIZE \ + (ERROR_LOG_LIMIT_SIZE + IO_ERROR_LOG_MESSAGE_HEADER_LENGTH) +#define IO_ERROR_LOG_MESSAGE_LENGTH \ + ((PORT_MAXIMUM_MESSAGE_LENGTH > ERROR_LOG_MESSAGE_LIMIT_SIZE) ? \ + ERROR_LOG_MESSAGE_LIMIT_SIZE : \ + PORT_MAXIMUM_MESSAGE_LENGTH) +#define ERROR_LOG_MAXIMUM_SIZE (IO_ERROR_LOG_MESSAGE_LENGTH - \ + IO_ERROR_LOG_MESSAGE_HEADER_LENGTH) typedef struct _CONTROLLER_OBJECT { CSHORT Type; Modified: trunk/reactos/ntoskrnl/include/internal/io.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/io.h (original) +++ trunk/reactos/ntoskrnl/include/internal/io.h Sat Jul 1 07:36:15 2006 @@ -217,6 +217,29 @@ PKINTERRUPT Interrupt[MAXIMUM_PROCESSORS]; KSPIN_LOCK SpinLock; } IO_INTERRUPT, *PIO_INTERRUPT; + +// +// I/O Error Log Packet Header +// +typedef struct _ERROR_LOG_ENTRY +{ + CSHORT Type; + CSHORT Size; + LIST_ENTRY ListEntry; + PDEVICE_OBJECT DeviceObject; + PDRIVER_OBJECT DriverObject; + LARGE_INTEGER TimeStamp; +} ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY; + +// +// Event Log LPC Message +// +typedef struct _ELF_API_MSG +{ + PORT_MESSAGE h; + ULONG Unknown[2]; + IO_ERROR_LOG_MESSAGE IoErrorMessage; +} ELF_API_MSG, *PELF_API_MSG; // // To simplify matters, the kernel is made to support both the checked and free @@ -604,10 +627,16 @@ // // Error Logging Routines // - -NTSTATUS +VOID +NTAPI IopInitErrorLog( VOID +); + +VOID +NTAPI +IopLogWorker( + IN PVOID Parameter ); // Modified: trunk/reactos/ntoskrnl/include/internal/tag.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/tag.h (original) +++ trunk/reactos/ntoskrnl/include/internal/tag.h Sat Jul 1 07:36:15 2006 @@ -49,6 +49,9 @@ #define IO_SMALLIRP_CPU TAG('I', 'r', 'p', 'S') #define IOC_TAG1 TAG('I', 'p', 'c', ' ') #define IOC_CPU TAG('I', 'p', 'c', 'P') +#define TAG_APC TAG('K', 'A', 'P', 'C') +#define TAG_IO TAG('I', 'o', ' ', ' ') +#define TAG_ERROR_LOG TAG('I', 'o', 'E', 'r') /* formerly located in io/work.c */ #define TAG_IOWI TAG('I', 'O', 'W', 'I') Modified: trunk/reactos/ntoskrnl/io/error.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/error.c?rev=22…
============================================================================== --- trunk/reactos/ntoskrnl/io/error.c (original) +++ trunk/reactos/ntoskrnl/io/error.c Sat Jul 1 07:36:15 2006 @@ -1,13 +1,11 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/io/errlog.c - * PURPOSE: Error logging - * - * PROGRAMMERS: David Welch (welch(a)cwcom.net) +/* + * 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(a)reactos.org) + * Eric Kohl */ - /* INCLUDES *****************************************************************/ #include <ntoskrnl.h> @@ -16,456 +14,457 @@ /* TYPES *********************************************************************/ -typedef struct _ERROR_LOG_ENTRY -{ - LIST_ENTRY Entry; - LARGE_INTEGER TimeStamp; - PVOID IoObject; - ULONG PacketSize; -} ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY; - -typedef struct _LOG_WORKER_DPC -{ - KDPC Dpc; - KTIMER Timer; -} LOG_WORKER_DPC, *PLOG_WORKER_DPC; - - -static VOID STDCALL -IopLogWorker (PVOID Parameter); - +typedef struct _IOP_ERROR_LOG_WORKER_DPC +{ + KDPC Dpc; + KTIMER Timer; +} IOP_ERROR_LOG_WORKER_DPC, *PIOP_ERROR_LOG_WORKER_DPC; /* GLOBALS *******************************************************************/ -static KSPIN_LOCK IopAllocationLock; -static ULONG IopTotalLogSize; - -static KSPIN_LOCK IopLogListLock; -static LIST_ENTRY IopLogListHead; - -static BOOLEAN IopLogWorkerRunning = FALSE; -static BOOLEAN IopLogPortConnected = FALSE; -static HANDLE IopLogPort; - - -/* FUNCTIONS *****************************************************************/ - -NTSTATUS -IopInitErrorLog (VOID) -{ - IopTotalLogSize = 0; - KeInitializeSpinLock (&IopAllocationLock); - - KeInitializeSpinLock (&IopLogListLock); - InitializeListHead (&IopLogListHead); - - return STATUS_SUCCESS; -} - - -static VOID STDCALL -IopLogDpcRoutine (PKDPC Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - PWORK_QUEUE_ITEM LogWorkItem; - - DPRINT ("\nIopLogDpcRoutine() called\n"); - - /* Release the WorkerDpc struct */ - ExFreePool (DeferredContext); - - /* Allocate, initialize and restart a work item */ - LogWorkItem = ExAllocatePool (NonPagedPool, - sizeof(WORK_QUEUE_ITEM)); - if (LogWorkItem == NULL) - { - IopLogWorkerRunning = FALSE; - return; - } - - ExInitializeWorkItem (LogWorkItem, - IopLogWorker, - LogWorkItem); - - ExQueueWorkItem (LogWorkItem, - DelayedWorkQueue); -} - - -static VOID -IopRestartLogWorker (VOID) -{ - PLOG_WORKER_DPC WorkerDpc; - LARGE_INTEGER Timeout; - - DPRINT ("IopRestartWorker() called\n"); - - WorkerDpc = ExAllocatePool (NonPagedPool, - sizeof(LOG_WORKER_DPC)); - if (WorkerDpc == NULL) - { - 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); -} - - -static BOOLEAN -IopConnectLogPort (VOID) -{ - UNICODE_STRING PortName; - NTSTATUS Status; - - DPRINT ("IopConnectLogPort() called\n"); - - RtlInitUnicodeString (&PortName, - L"\\ErrorLogPort"); - - Status = ZwConnectPort (&IopLogPort, - &PortName, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT ("ZwConnectPort() failed (Status %lx)\n", Status); - return FALSE; - } - - DPRINT ("IopConnectLogPort() done\n"); - - return TRUE; -} - - -static VOID STDCALL -IopLogWorker (PVOID Parameter) -{ - PERROR_LOG_ENTRY LogEntry; - PPORT_MESSAGE Request; - PIO_ERROR_LOG_MESSAGE Message; - PIO_ERROR_LOG_PACKET Packet; - KIRQL Irql; - NTSTATUS Status; - - UCHAR Buffer[256]; - POBJECT_NAME_INFORMATION ObjectNameInfo; - ULONG ReturnedLength; - PWCHAR DriverName; - ULONG DriverNameLength; - - DPRINT ("IopLogWorker() called\n"); - - /* Release the work item */ - ExFreePool (Parameter); - - /* Connect to the error log port */ - if (IopLogPortConnected == FALSE) - { - if (IopConnectLogPort () == FALSE) - { - IopRestartLogWorker (); - return; - } - - IopLogPortConnected = TRUE; - } - - while (TRUE) - { - /* Remove last entry from the list */ - KeAcquireSpinLock (&IopLogListLock, - &Irql); - - if (!IsListEmpty (&IopLogListHead)) - { - LogEntry = CONTAINING_RECORD (IopLogListHead.Blink, - ERROR_LOG_ENTRY, - Entry); - RemoveEntryList (&LogEntry->Entry); - } - else - { - LogEntry = NULL; - } - - KeReleaseSpinLock (&IopLogListLock, - Irql); - - if (LogEntry == NULL) - { - DPRINT ("No message in log list\n"); - break; - } - - /* Get pointer to the log packet */ - Packet = (PIO_ERROR_LOG_PACKET)((ULONG_PTR)LogEntry + sizeof(ERROR_LOG_ENTRY)); - - - /* Get driver or device name */ - ObjectNameInfo = (POBJECT_NAME_INFORMATION)Buffer; - Status = ObQueryNameString (LogEntry->IoObject, - ObjectNameInfo, - 256, - &ReturnedLength); - if (NT_SUCCESS(Status)) - { - DPRINT ("ReturnedLength: %lu\n", ReturnedLength); - DPRINT ("Length: %hu\n", ObjectNameInfo->Name.Length); - DPRINT ("MaximumLength: %hu\n", ObjectNameInfo->Name.MaximumLength); - DPRINT ("Object: %wZ\n", &ObjectNameInfo->Name); - - DriverName = wcsrchr(ObjectNameInfo->Name.Buffer, L'\\'); - if (DriverName != NULL) - DriverName++; - else - DriverName = ObjectNameInfo->Name.Buffer; - - DriverNameLength = wcslen (DriverName) * sizeof(WCHAR); - DPRINT ("Driver name '%S'\n", DriverName); - } - else - { - DriverName = NULL; - DriverNameLength = 0; - } - - /* Allocate request buffer */ - Request = ExAllocatePool (NonPagedPool, - sizeof(PORT_MESSAGE) + PORT_MAXIMUM_MESSAGE_LENGTH); - if (Request == NULL) - { - DPRINT ("Failed to allocate request buffer!\n"); - - /* Requeue log message and restart the worker */ - ExInterlockedInsertTailList (&IopLogListHead, - &LogEntry->Entry, - &IopLogListLock); - IopRestartLogWorker (); - - return; - } - - /* Initialize the log message */ - Message = (PIO_ERROR_LOG_MESSAGE)(Request + 1); - Message->Type = IO_TYPE_ERROR_MESSAGE; - Message->Size = - sizeof(IO_ERROR_LOG_MESSAGE) - sizeof(IO_ERROR_LOG_PACKET) + - LogEntry->PacketSize + DriverNameLength; - Message->DriverNameLength = (USHORT)DriverNameLength; - Message->TimeStamp.QuadPart = LogEntry->TimeStamp.QuadPart; - Message->DriverNameOffset = (DriverName != NULL) ? LogEntry->PacketSize : 0; - - /* Copy error log packet */ - RtlCopyMemory (&Message->EntryData, - Packet, - LogEntry->PacketSize); - - /* Copy driver or device name */ - RtlCopyMemory ((PVOID)((ULONG_PTR)Message + Message->DriverNameOffset), - DriverName, - DriverNameLength); - - DPRINT ("SequenceNumber %lx\n", Packet->SequenceNumber); - - Request->u1.s1.DataLength = Message->Size; - Request->u1.s1.TotalLength = - Request->u1.s1.DataLength + sizeof(PPORT_MESSAGE); - - /* Send the error message to the log port */ - Status = ZwRequestPort (IopLogPort, - Request); - - /* Release request buffer */ - ExFreePool (Request); - - if (!NT_SUCCESS(Status)) - { - DPRINT ("ZwRequestPort() failed (Status %lx)\n", Status); - - /* Requeue log message and restart the worker */ - ExInterlockedInsertTailList (&IopLogListHead, - &LogEntry->Entry, - &IopLogListLock); - IopRestartLogWorker (); - - return; - } - - /* Release error log entry */ - KeAcquireSpinLock (&IopAllocationLock, - &Irql); - - IopTotalLogSize -= (LogEntry->PacketSize - sizeof(ERROR_LOG_ENTRY)); - ExFreePool (LogEntry); - - KeReleaseSpinLock (&IopAllocationLock, - Irql); - } - - IopLogWorkerRunning = FALSE; - - DPRINT ("IopLogWorker() done\n"); -} - - -/* - * @implemented - */ -PVOID STDCALL -IoAllocateErrorLogEntry (IN PVOID IoObject, - IN UCHAR EntrySize) -{ - PERROR_LOG_ENTRY LogEntry; - ULONG LogEntrySize; - KIRQL Irql; - - DPRINT("IoAllocateErrorLogEntry() called\n"); - - if (IoObject == NULL) - return NULL; - - KeAcquireSpinLock (&IopAllocationLock, - &Irql); - - if (IopTotalLogSize > PAGE_SIZE) - { - KeReleaseSpinLock (&IopAllocationLock, - Irql); - return NULL; - } - - LogEntrySize = sizeof(ERROR_LOG_ENTRY) + EntrySize; - LogEntry = ExAllocatePool (NonPagedPool, - LogEntrySize); - if (LogEntry == NULL) - { - KeReleaseSpinLock (&IopAllocationLock, - Irql); - return NULL; - } - - IopTotalLogSize += EntrySize; - - LogEntry->IoObject = IoObject; - LogEntry->PacketSize = LogEntrySize; - - KeReleaseSpinLock (&IopAllocationLock, - Irql); - - return (PVOID)((ULONG_PTR)LogEntry + sizeof(ERROR_LOG_ENTRY)); -} - - -/* - * @implemented - */ -VOID STDCALL -IoFreeErrorLogEntry(IN PVOID ElEntry) -{ - PERROR_LOG_ENTRY LogEntry; - KIRQL Irql; - - DPRINT("IoFreeErrorLogEntry() called\n"); - - if (ElEntry == NULL) - return; - - LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY)); - - KeAcquireSpinLock(&IopAllocationLock, - &Irql); - - IopTotalLogSize -= (LogEntry->PacketSize - sizeof(ERROR_LOG_ENTRY)); - ExFreePool(LogEntry); - - KeReleaseSpinLock(&IopAllocationLock, - Irql); -} - - -/* - * @implemented - */ -VOID STDCALL -IoWriteErrorLogEntry (IN PVOID ElEntry) -{ - PWORK_QUEUE_ITEM LogWorkItem; - PERROR_LOG_ENTRY LogEntry; - KIRQL Irql; - - DPRINT("IoWriteErrorLogEntry() called\n"); - - LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY)); - - /* Get time stamp */ - KeQuerySystemTime (&LogEntry->TimeStamp); - - KeAcquireSpinLock (&IopLogListLock, - &Irql); - - InsertHeadList (&IopLogListHead, - &LogEntry->Entry); - - if (IopLogWorkerRunning == FALSE) - { - LogWorkItem = ExAllocatePool (NonPagedPool, - sizeof(WORK_QUEUE_ITEM)); - if (LogWorkItem != NULL) - { - ExInitializeWorkItem (LogWorkItem, - IopLogWorker, - LogWorkItem); - - ExQueueWorkItem (LogWorkItem, - DelayedWorkQueue); - - IopLogWorkerRunning = TRUE; - } - } - - KeReleaseSpinLock (&IopLogListLock, - Irql); - - DPRINT("IoWriteErrorLogEntry() done\n"); -} - -VOID -STDCALL -IopFreeApc(PKAPC Apc, - PKNORMAL_ROUTINE *NormalRoutine, - PVOID *NormalContext, - PVOID *SystemArgument1, - PVOID *SystemArgument2) +LONG IopTotalLogSize; +LIST_ENTRY IopLogListHead; +KSPIN_LOCK IopLogListLock; + +BOOLEAN IopLogWorkerRunning; +BOOLEAN IopLogPortConnected; +HANDLE IopLogPort; +WORK_QUEUE_ITEM IopErrorLogWorkItem; + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +IopInitErrorLog(VOID) +{ + /* Initialize the locks and list head */ + KeInitializeSpinLock(&IopLogListLock); + InitializeListHead(&IopLogListHead); +} + +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(&IopLogListHead)) + { + /* List is empty, disable the worker and return NULL */ + IopLogWorkerRunning = FALSE; + ListEntry = NULL; + } + else + { + /* Otherwise, remove an entry */ + ListEntry = RemoveHeadList(&IopLogListHead); + } + + /* 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)) + { + /* Remmeber 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 */ + RtlMoveMemory(&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 = (PVOID)ALIGN_UP(StringBuffer, WCHAR); + + /* Set the offset for the driver's name to the current buffer */ + ErrorMessage->DriverNameOffset = (ULONG)(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; + } + + /* 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)); + RtlMoveMemory(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 - + 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)); + RtlMoveMemory(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 */ + RtlMoveMemory(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(&IopLogListHead, + &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, + -(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 -STDCALL -IopRaiseHardError(PKAPC Apc, - PKNORMAL_ROUTINE *NormalRoutine, - PVOID *NormalContext, - PVOID *SystemArgument1, - PVOID *SystemArgument2) +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; @@ -477,14 +476,141 @@ IoCompleteRequest(Irp, IO_DISK_INCREMENT); } +/* PUBLIC FUNCTIONS **********************************************************/ + /* * @implemented */ -VOID -STDCALL -IoRaiseHardError(PIRP Irp, - PVPB Vpb, - PDEVICE_OBJECT RealDeviceObject) +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, + -(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 */ + KEBUGCHECK(0); + 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(&IopLogListHead, &LogEntry->ListEntry); + + /* Check if the worker is runnign */ + if (!IopLogWorkerRunning) + { + /* It's not, initialize it and queue it */ + ExInitializeWorkItem(&IopErrorLogWorkItem, + IopLogWorker, + &IopErrorLogWorkItem); + ExQueueWorkItem(&IopErrorLogWorkItem, DelayedWorkQueue); + IopLogWorkerRunning = TRUE; + } + + /* 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; @@ -501,7 +627,7 @@ /* Setup an APC */ ErrorApc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), - TAG('K', 'A', 'P', 'C')); + TAG_APC); KeInitializeApc(ErrorApc, &Thread->Tcb, Irp->ApcEnvironment, @@ -519,39 +645,31 @@ * @unimplemented */ BOOLEAN -STDCALL -IoRaiseInformationalHardError(NTSTATUS ErrorStatus, - PUNICODE_STRING String, - PKTHREAD Thread) +NTAPI +IoRaiseInformationalHardError(IN NTSTATUS ErrorStatus, + IN PUNICODE_STRING String, + IN PKTHREAD Thread) { UNIMPLEMENTED; return(FALSE); } -/********************************************************************** - * NAME EXPORTED - * IoSetThreadHardErrorMode@4 - * - * ARGUMENTS - * HardErrorEnabled - * TRUE : enable hard errors processing; - * FALSE: do NOT process hard errors. - * - * RETURN VALUE - * Previous value for the current thread's hard errors - * processing policy. - * +/* * @implemented */ BOOLEAN -STDCALL +NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled) { - BOOLEAN PreviousHEM = (BOOLEAN)(NtCurrentTeb()->HardErrorDisabled); - - NtCurrentTeb()->HardErrorDisabled = ((TRUE == HardErrorEnabled) ? FALSE : TRUE); - - return((TRUE == PreviousHEM) ? FALSE : TRUE); + 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 */
18 years, 5 months
1
0
0
0
← Newer
1
...
64
65
66
67
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
Results per page:
10
25
50
100
200