- Delete named objects from the namespace when the last handle is closed, unless the object is a permanent object - IoCreateDevice should create a permanent object for named devices Modified: trunk/reactos/ntoskrnl/include/internal/ob.h Modified: trunk/reactos/ntoskrnl/io/device.c Modified: trunk/reactos/ntoskrnl/ob/handle.c Modified: trunk/reactos/ntoskrnl/ob/object.c _____
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h --- trunk/reactos/ntoskrnl/include/internal/ob.h 2005-04-19 15:06:18 UTC (rev 14702) +++ trunk/reactos/ntoskrnl/include/internal/ob.h 2005-04-19 17:12:03 UTC (rev 14703) @@ -272,7 +272,6 @@
PVOID* ReturnedObject, PUNICODE_STRING RemainingPath, POBJECT_TYPE ObjectType); -VOID ObDeleteHandleTable(struct _EPROCESS* Process);
NTSTATUS ObpQueryHandleAttributes(HANDLE Handle, _____
Modified: trunk/reactos/ntoskrnl/io/device.c --- trunk/reactos/ntoskrnl/io/device.c 2005-04-19 15:06:18 UTC (rev 14702) +++ trunk/reactos/ntoskrnl/io/device.c 2005-04-19 17:12:03 UTC (rev 14703) @@ -385,9 +385,15 @@
/* Initialize the Object Attributes */ InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL, NULL);
- /* Honour exclusive flag */ + /* Honor exclusive flag */ ObjectAttributes.Attributes |= OBJ_EXCLUSIVE;
+ /* Create a permanent object for named devices */ + if (DeviceName != NULL) + { + ObjectAttributes.Attributes |= OBJ_PERMANENT; + } + /* Align the Extension Size to 8-bytes */ AlignedDeviceExtensionSize = (DeviceExtensionSize + 7) &~ 7; DPRINT("AlignedDeviceExtensionSize %x\n", AlignedDeviceExtensionSize); _____
Modified: trunk/reactos/ntoskrnl/ob/handle.c --- trunk/reactos/ntoskrnl/ob/handle.c 2005-04-19 15:06:18 UTC (rev 14702) +++ trunk/reactos/ntoskrnl/ob/handle.c 2005-04-19 17:12:03 UTC (rev 14703) @@ -48,13 +48,6 @@
/* FUNCTIONS ***************************************************************/
-VOID -STDCALL -ObKillProcess(PEPROCESS Process) -{ - ObDeleteHandleTable(Process); -} - static VOID ObpDecrementHandleCount(PVOID ObjectBody) { @@ -71,6 +64,15 @@
if(NewHandleCount == 0) { + if(ObjectHeader->Parent != NULL && !ObjectHeader->Permanent) + { + /* delete the object from the namespace when the last handle got closed. + Only do this if it's actually been inserted into the namespace and + if it's not a permanent object. */ + ObpRemoveEntryDirectory(ObjectHeader); + } + + /* remove the keep-alive reference */ ObDereferenceObject(ObjectBody); } } @@ -519,18 +521,6 @@ ObpDecrementHandleCount(ObjectBody); }
-VOID ObDeleteHandleTable(PEPROCESS Process) -/* - * FUNCTION: Deletes the handle table associated with a process - */ -{ - PAGED_CODE(); - - ExDestroyHandleTable(Process->ObjectTable, - DeleteHandleCallback, - Process); -} - static BOOLEAN STDCALL DuplicateHandleCallback(PHANDLE_TABLE HandleTable, PHANDLE_TABLE_ENTRY HandleTableEntry, @@ -583,6 +573,18 @@ }
+VOID +STDCALL +ObKillProcess(PEPROCESS Process) +{ + PAGED_CODE(); + + ExDestroyHandleTable(Process->ObjectTable, + DeleteHandleCallback, + Process); +} + + NTSTATUS ObCreateHandle(PEPROCESS Process, PVOID ObjectBody, _____
Modified: trunk/reactos/ntoskrnl/ob/object.c --- trunk/reactos/ntoskrnl/ob/object.c 2005-04-19 15:06:18 UTC (rev 14702) +++ trunk/reactos/ntoskrnl/ob/object.c 2005-04-19 17:12:03 UTC (rev 14703) @@ -1021,6 +1021,7 @@
ObpDeleteObjectDpcLevel(IN POBJECT_HEADER ObjectHeader, IN LONG OldRefCount) { +#if 0 if (ObjectHeader->RefCount < 0) { CPRINT("Object %p/%p has invalid reference count (%d)\n", @@ -1036,6 +1037,7 @@ ObjectHeader->HandleCount); KEBUGCHECK(0); } +#endif
switch (KeGetCurrentIrql ())
weiden@svn.reactos.com wrote:
Modified: trunk/reactos/ntoskrnl/io/device.c --- trunk/reactos/ntoskrnl/io/device.c 2005-04-19 15:06:18 UTC (rev 14702) +++ trunk/reactos/ntoskrnl/io/device.c 2005-04-19 17:12:03 UTC (rev 14703) @@ -385,9 +385,15 @@
/* Initialize the Object Attributes */ InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL,NULL);
- /* Honour exclusive flag */
/* Honor exclusive flag */ ObjectAttributes.Attributes |= OBJ_EXCLUSIVE;
/* Create a permanent object for named devices */
if (DeviceName != NULL)
{
ObjectAttributes.Attributes |= OBJ_PERMANENT;}
/* Align the Extension Size to 8-bytes */ AlignedDeviceExtensionSize = (DeviceExtensionSize + 7) &~ 7; DPRINT("AlignedDeviceExtensionSize %x\n",
AlignedDeviceExtensionSize); _____
I think this is not correct. If the name is permanent, IoDeleteDevice isn't able to delete a device. Currently it exist a bug, which does also prevent from deleting a device. IoDeleteDevice doesn't dereference the driver object.
- Hartmut
Hartmut Birr wrote:
weiden@svn.reactos.com wrote: I think this is not correct.
It is. A named object is removed from the object namespace as soon as the last handle got closed (not when the reference counter drops to 0!). When you run WinObj from sysinternals and view the properties of some devices loaded, you'll notice that the handle count is 0, which means they have to be permanent objects, otherwise they would've been deleted from the object name space.
If the name is permanent, IoDeleteDevice isn't able to delete a device. Currently it exist a bug, which does also prevent from deleting a device. IoDeleteDevice doesn't dereference the driver object.
IoDeleteDevice certainly should convert the object to a temporary object then, which should cause it to be removed from the namespace if there's no handles present. It should be rather easy to fix, I'll do it tonight.
Best Regards, Thomas
Thomas Weidenmueller wrote:
Hartmut Birr wrote:
weiden@svn.reactos.com wrote: I think this is not correct.
It is. A named object is removed from the object namespace as soon as the last handle got closed (not when the reference counter drops to 0!). When you run WinObj from sysinternals and view the properties of some devices loaded, you'll notice that the handle count is 0, which means they have to be permanent objects, otherwise they would've been deleted from the object name space.
A permanent object is never removed from the object name space.
Since rev 14643, I'm not able to boot ros on my test system. Each changes in ntoskrnl\io\ does change the error messages. My test system has only the a cdrom on the ide controller. The disk is a scsi one.
- Hartmut
Hartmut Birr wrote:
A permanent object is never removed from the object name space.
That's why the object is converted to a temporary object before it can be deleted. Temporary objects with 0 handles cannot be in the namespace, they get removed as soon as the last handle is closed.
Since rev 14643, I'm not able to boot ros on my test system. Each changes in ntoskrnl\io\ does change the error messages. My test system has only the a cdrom on the ide controller. The disk is a scsi one.
I don't know what and why alex changed stuff in there, but these changes I did certainly shouldn't break booting ros, at least it works fine for me.
I'm *pretty* sure these objects are permanent, if you want I'll write a driver to proof this on windows tomorrow or thursday.
Best Regards, Thomas
Thomas Weidenmueller wrote:
Hartmut Birr wrote:
Since rev 14643, I'm not able to boot ros on my test system. Each changes in ntoskrnl\io\ does change the error messages. My test system has only the a cdrom on the ide controller. The disk is a scsi one.
I don't know what and why alex changed stuff in there, but these changes I did certainly shouldn't break booting ros, at least it works fine for me.
I'm *pretty* sure these objects are permanent, if you want I'll write a driver to proof this on windows tomorrow or thursday.
It seems that the problem is the additional reference of the created device object. If I disable line #515 (ntoskrnl\io\device.c), my test pc can boot again.
- Hartmut
Hartmut Birr wrote:
Currently it exist a bug, which does also prevent from deleting a device. IoDeleteDevice doesn't dereference the driver object.
The attached patch should fix these issues.
Best Regards, Thomas
Index: ob/ntobj.c =================================================================== --- ob/ntobj.c (revision 14704) +++ ob/ntobj.c (working copy) @@ -224,6 +224,12 @@
ObjectHeader = BODY_TO_HEADER(ObjectBody); ObjectHeader->Permanent = Permanent; + + if (ObjectHeader->HandleCount == 0 && !Permanent && ObjectHeader->Parent != NULL) + { + /* Remove the object from the namespace */ + ObpRemoveEntryDirectory(ObjectHeader); + } }
/********************************************************************** Index: io/device.c =================================================================== --- io/device.c (revision 14704) +++ io/device.c (working copy) @@ -557,6 +557,15 @@
/* I guess this should be removed later... but it shouldn't cause problems */ DeviceObject->DeviceObjectExtension->ExtensionFlags |= DOE_DELETE_PENDING; + + /* Make the object temporary. This should automatically remove the device + from the namespace */ + ObMakeTemporaryObject(DeviceObject); + + /* Dereference the driver object */ + ObDereferenceObject(DeviceObject->DriverObject); + + /* Remove the keep-alive reference */ ObDereferenceObject(DeviceObject); }