RtlGenericTable

Hi everyone!

I have some set of data stored in RtlGenericTable and at some point I
need to go through all its entries and delete some of them. What would
be the best way to do it, so I can safely delete some entries and still
be able to go through remaining ones without having to restart enum? DDK
is a bit confusing on that.

TIA,

Vladimir

First, do not play. Otherwise you will flatten the tree and lose the
performance gains of the MRU list.

See if this helps; remember, do not patent this code :slight_smile:

NTSTATUS _BFilterUnregisterProcess
(
PEPROCESS Process
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PROCESS_RECORD processRecord;
PPROCESS_RECORD pProcessRecord;
KIRQL oldIrql;
RtlZeroMemory(&processRecord, sizeof (PROCESS_RECORD));
processRecord.ProcessId = Process;
KeAcquireSpinLock(&gProcessTableSpinLock, &oldIrql);
pProcessRecord = RtlLookupElementGenericTable(&gProcessTable,
&processRecord);
if (pProcessRecord != NULL)
{
PFILE_RECORD restartFileRecord = NULL;
PFILE_RECORD fileRecord = NULL;
KdPrint((“BFILTER: Unregistering process.\n”));
// Purge file object table.
if (RtlNumberGenericTableElements(&pProcessRecord->FileTable) != 0)
for
(
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord);
fileRecord != NULL;
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord)
)
{
RtlDeleteElementGenericTable(&pProcessRecord->FileTable,
fileRecord);
restartFileRecord = NULL;
}
// Purge the xlat table.
while (!IsListEmpty(&pProcessRecord->XlatListHead))
{
PVOID entry =
RemoveHeadList(&pProcessRecord->XlatListHead);
if (entry != NULL)
ExFreePool(entry);
}
// Remove process record entry.
RtlDeleteElementGenericTable(&gProcessTable,
pProcessRecord);
}
else
KdPrint((“BFILTER: Process not registered.\n”));
KeReleaseSpinLock(&gProcessTableSpinLock, oldIrql);
return (ntStatus);
}

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir Chtchetkine
Sent: Tuesday, February 24, 2004 10:03 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RtlGenericTable

Hi everyone!

I have some set of data stored in RtlGenericTable and at some point I
need to go through all its entries and delete some of them. What would
be the best way to do it, so I can safely delete some entries and still
be able to go through remaining ones without having to restart enum? DDK
is a bit confusing on that.

TIA,

Vladimir


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Also, if you are using XP and above, I recommend using the AVL table; AVL is
a height balanced binary tree and does not suffer from re-ordering on
access. And, I do not think that A, V or L ever patented the tree structure,
so it is a public algorithm.

Jamey

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir Chtchetkine
Sent: Tuesday, February 24, 2004 10:03 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RtlGenericTable

Hi everyone!

I have some set of data stored in RtlGenericTable and at some point I
need to go through all its entries and delete some of them. What would
be the best way to do it, so I can safely delete some entries and still
be able to go through remaining ones without having to restart enum? DDK
is a bit confusing on that.

TIA,

Vladimir


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Thanks, Jamey!

That’s exactly why I said DDK was confusing. From one side splaying
would flatten table to a linked list so I can safely delete an entry and
continue enum. But this degrades the table. From other side deleting an
entry without splaying may break the search sequence. Anyway…

It looks like in your code you simply restart enum over and over again
in each loop by setting restartFileRecord = NULL; (last statement inside
the loop). And that’s (restarting the enum) was exactly the case I
wanted to avoid…

I think that I will simply run a linked list along and in complete sync
with the table, will do lookups from the table and enums from the list.
Unless somebody knows a way how to implement this with table only…

P.S. :slight_smile:

-----Original Message-----
From: Jamey Kirby [mailto:xxxxx@storagecraft.com]
Sent: Tuesday, February 24, 2004 11:15 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

First, do not play. Otherwise you will flatten the tree and lose the
performance gains of the MRU list.

See if this helps; remember, do not patent this code :slight_smile:

NTSTATUS _BFilterUnregisterProcess
(
PEPROCESS Process
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PROCESS_RECORD processRecord;
PPROCESS_RECORD pProcessRecord;
KIRQL oldIrql;
RtlZeroMemory(&processRecord, sizeof (PROCESS_RECORD));
processRecord.ProcessId = Process;
KeAcquireSpinLock(&gProcessTableSpinLock, &oldIrql);
pProcessRecord = RtlLookupElementGenericTable(&gProcessTable,
&processRecord);
if (pProcessRecord != NULL)
{
PFILE_RECORD restartFileRecord = NULL;
PFILE_RECORD fileRecord = NULL;
KdPrint((“BFILTER: Unregistering process.\n”));
// Purge file object table.
if (RtlNumberGenericTableElements(&pProcessRecord->FileTable) !=
0)
for
(
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord);
fileRecord != NULL;
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord)
)
{
RtlDeleteElementGenericTable(&pProcessRecord->FileTable,
fileRecord);
restartFileRecord = NULL;
}
// Purge the xlat table.
while (!IsListEmpty(&pProcessRecord->XlatListHead))
{
PVOID entry =
RemoveHeadList(&pProcessRecord->XlatListHead);
if (entry != NULL)
ExFreePool(entry);
}
// Remove process record entry.
RtlDeleteElementGenericTable(&gProcessTable,
pProcessRecord);
}
else
KdPrint((“BFILTER: Process not registered.\n”));
KeReleaseSpinLock(&gProcessTableSpinLock, oldIrql);
return (ntStatus);
}

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir
Chtchetkine
Sent: Tuesday, February 24, 2004 10:03 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RtlGenericTable

Hi everyone!

I have some set of data stored in RtlGenericTable and at some point I
need to go through all its entries and delete some of them. What would
be the best way to do it, so I can safely delete some entries and still
be able to go through remaining ones without having to restart enum? DDK
is a bit confusing on that.

TIA,

Vladimir


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as:
xxxxx@borland.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

But it is not really an enumeration. In the code I sent, it gets the first
record, deletes it and gets the first record again. So, even though it is
calling the enumeration function, it is just deleting the elements from the
top down; like popping off of a stack.

Also note RtlEnumerateGenericTableWithoutSplaying(). This prevents the list
from splaying on access and will not flatten this tree to a list.

Why will this not work in your case?

Jamey

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir Chtchetkine
Sent: Tuesday, February 24, 2004 11:44 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

Thanks, Jamey!

That’s exactly why I said DDK was confusing. From one side splaying
would flatten table to a linked list so I can safely delete an entry and
continue enum. But this degrades the table. From other side deleting an
entry without splaying may break the search sequence. Anyway…

It looks like in your code you simply restart enum over and over again
in each loop by setting restartFileRecord = NULL; (last statement inside
the loop). And that’s (restarting the enum) was exactly the case I
wanted to avoid…

I think that I will simply run a linked list along and in complete sync
with the table, will do lookups from the table and enums from the list.
Unless somebody knows a way how to implement this with table only…

P.S. :slight_smile:

-----Original Message-----
From: Jamey Kirby [mailto:xxxxx@storagecraft.com]
Sent: Tuesday, February 24, 2004 11:15 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

First, do not play. Otherwise you will flatten the tree and lose the
performance gains of the MRU list.

See if this helps; remember, do not patent this code :slight_smile:

NTSTATUS _BFilterUnregisterProcess
(
PEPROCESS Process
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PROCESS_RECORD processRecord;
PPROCESS_RECORD pProcessRecord;
KIRQL oldIrql;
RtlZeroMemory(&processRecord, sizeof (PROCESS_RECORD));
processRecord.ProcessId = Process;
KeAcquireSpinLock(&gProcessTableSpinLock, &oldIrql);
pProcessRecord = RtlLookupElementGenericTable(&gProcessTable,
&processRecord);
if (pProcessRecord != NULL)
{
PFILE_RECORD restartFileRecord = NULL;
PFILE_RECORD fileRecord = NULL;
KdPrint((“BFILTER: Unregistering process.\n”));
// Purge file object table.
if (RtlNumberGenericTableElements(&pProcessRecord->FileTable) !=
0)
for
(
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord);
fileRecord != NULL;
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord)
)
{
RtlDeleteElementGenericTable(&pProcessRecord->FileTable,
fileRecord);
restartFileRecord = NULL;
}
// Purge the xlat table.
while (!IsListEmpty(&pProcessRecord->XlatListHead))
{
PVOID entry =
RemoveHeadList(&pProcessRecord->XlatListHead);
if (entry != NULL)
ExFreePool(entry);
}
// Remove process record entry.
RtlDeleteElementGenericTable(&gProcessTable,
pProcessRecord);
}
else
KdPrint((“BFILTER: Process not registered.\n”));
KeReleaseSpinLock(&gProcessTableSpinLock, oldIrql);
return (ntStatus);
}

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir
Chtchetkine
Sent: Tuesday, February 24, 2004 10:03 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RtlGenericTable

Hi everyone!

I have some set of data stored in RtlGenericTable and at some point I
need to go through all its entries and delete some of them. What would
be the best way to do it, so I can safely delete some entries and still
be able to go through remaining ones without having to restart enum? DDK
is a bit confusing on that.

TIA,

Vladimir


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as:
xxxxx@borland.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Jamey:

It’s not going to work for me because I may want to delete an entry
somewhere in the middle of the table and then continue enumerating
remaining entries. I use method that you’ve sent to empty the table but
what I need to do in my case is to delete just some of the entries.

Regards,

Vladimir

-----Original Message-----
From: Jamey Kirby [mailto:xxxxx@storagecraft.com]
Sent: Tuesday, February 24, 2004 11:52 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

But it is not really an enumeration. In the code I sent, it gets the
first
record, deletes it and gets the first record again. So, even though it
is
calling the enumeration function, it is just deleting the elements from
the
top down; like popping off of a stack.

Also note RtlEnumerateGenericTableWithoutSplaying(). This prevents the
list
from splaying on access and will not flatten this tree to a list.

Why will this not work in your case?

Jamey

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir
Chtchetkine
Sent: Tuesday, February 24, 2004 11:44 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

Thanks, Jamey!

That’s exactly why I said DDK was confusing. From one side splaying
would flatten table to a linked list so I can safely delete an entry and
continue enum. But this degrades the table. From other side deleting an
entry without splaying may break the search sequence. Anyway…

It looks like in your code you simply restart enum over and over again
in each loop by setting restartFileRecord = NULL; (last statement inside
the loop). And that’s (restarting the enum) was exactly the case I
wanted to avoid…

I think that I will simply run a linked list along and in complete sync
with the table, will do lookups from the table and enums from the list.
Unless somebody knows a way how to implement this with table only…

P.S. :slight_smile:

-----Original Message-----
From: Jamey Kirby [mailto:xxxxx@storagecraft.com]
Sent: Tuesday, February 24, 2004 11:15 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

First, do not play. Otherwise you will flatten the tree and lose the
performance gains of the MRU list.

See if this helps; remember, do not patent this code :slight_smile:

NTSTATUS _BFilterUnregisterProcess
(
PEPROCESS Process
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PROCESS_RECORD processRecord;
PPROCESS_RECORD pProcessRecord;
KIRQL oldIrql;
RtlZeroMemory(&processRecord, sizeof (PROCESS_RECORD));
processRecord.ProcessId = Process;
KeAcquireSpinLock(&gProcessTableSpinLock, &oldIrql);
pProcessRecord = RtlLookupElementGenericTable(&gProcessTable,
&processRecord);
if (pProcessRecord != NULL)
{
PFILE_RECORD restartFileRecord = NULL;
PFILE_RECORD fileRecord = NULL;
KdPrint((“BFILTER: Unregistering process.\n”));
// Purge file object table.
if (RtlNumberGenericTableElements(&pProcessRecord->FileTable) !=
0)
for
(
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord);
fileRecord != NULL;
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord)
)
{
RtlDeleteElementGenericTable(&pProcessRecord->FileTable,
fileRecord);
restartFileRecord = NULL;
}
// Purge the xlat table.
while (!IsListEmpty(&pProcessRecord->XlatListHead))
{
PVOID entry =
RemoveHeadList(&pProcessRecord->XlatListHead);
if (entry != NULL)
ExFreePool(entry);
}
// Remove process record entry.
RtlDeleteElementGenericTable(&gProcessTable,
pProcessRecord);
}
else
KdPrint((“BFILTER: Process not registered.\n”));
KeReleaseSpinLock(&gProcessTableSpinLock, oldIrql);
return (ntStatus);
}

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir
Chtchetkine
Sent: Tuesday, February 24, 2004 10:03 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RtlGenericTable

Hi everyone!

I have some set of data stored in RtlGenericTable and at some point I
need to go through all its entries and delete some of them. What would
be the best way to do it, so I can safely delete some entries and still
be able to go through remaining ones without having to restart enum? DDK
is a bit confusing on that.

TIA,

Vladimir


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as:
xxxxx@borland.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as:
xxxxx@borland.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Then set the restart pointer to the proper value to continue on. No need to
start from the beginning of the tree.

Jamey

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir Chtchetkine
Sent: Tuesday, February 24, 2004 1:22 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

Jamey:

It’s not going to work for me because I may want to delete an entry
somewhere in the middle of the table and then continue enumerating
remaining entries. I use method that you’ve sent to empty the table but
what I need to do in my case is to delete just some of the entries.

Regards,

Vladimir

-----Original Message-----
From: Jamey Kirby [mailto:xxxxx@storagecraft.com]
Sent: Tuesday, February 24, 2004 11:52 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

But it is not really an enumeration. In the code I sent, it gets the
first
record, deletes it and gets the first record again. So, even though it
is
calling the enumeration function, it is just deleting the elements from
the
top down; like popping off of a stack.

Also note RtlEnumerateGenericTableWithoutSplaying(). This prevents the
list
from splaying on access and will not flatten this tree to a list.

Why will this not work in your case?

Jamey

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir
Chtchetkine
Sent: Tuesday, February 24, 2004 11:44 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

Thanks, Jamey!

That’s exactly why I said DDK was confusing. From one side splaying
would flatten table to a linked list so I can safely delete an entry and
continue enum. But this degrades the table. From other side deleting an
entry without splaying may break the search sequence. Anyway…

It looks like in your code you simply restart enum over and over again
in each loop by setting restartFileRecord = NULL; (last statement inside
the loop). And that’s (restarting the enum) was exactly the case I
wanted to avoid…

I think that I will simply run a linked list along and in complete sync
with the table, will do lookups from the table and enums from the list.
Unless somebody knows a way how to implement this with table only…

P.S. :slight_smile:

-----Original Message-----
From: Jamey Kirby [mailto:xxxxx@storagecraft.com]
Sent: Tuesday, February 24, 2004 11:15 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] RtlGenericTable

First, do not play. Otherwise you will flatten the tree and lose the
performance gains of the MRU list.

See if this helps; remember, do not patent this code :slight_smile:

NTSTATUS _BFilterUnregisterProcess
(
PEPROCESS Process
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PROCESS_RECORD processRecord;
PPROCESS_RECORD pProcessRecord;
KIRQL oldIrql;
RtlZeroMemory(&processRecord, sizeof (PROCESS_RECORD));
processRecord.ProcessId = Process;
KeAcquireSpinLock(&gProcessTableSpinLock, &oldIrql);
pProcessRecord = RtlLookupElementGenericTable(&gProcessTable,
&processRecord);
if (pProcessRecord != NULL)
{
PFILE_RECORD restartFileRecord = NULL;
PFILE_RECORD fileRecord = NULL;
KdPrint((“BFILTER: Unregistering process.\n”));
// Purge file object table.
if (RtlNumberGenericTableElements(&pProcessRecord->FileTable) !=
0)
for
(
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord);
fileRecord != NULL;
fileRecord =
RtlEnumerateGenericTableWithoutSplaying(&pProcessRecord->FileTable,
&restartFileRecord)
)
{
RtlDeleteElementGenericTable(&pProcessRecord->FileTable,
fileRecord);
restartFileRecord = NULL;
}
// Purge the xlat table.
while (!IsListEmpty(&pProcessRecord->XlatListHead))
{
PVOID entry =
RemoveHeadList(&pProcessRecord->XlatListHead);
if (entry != NULL)
ExFreePool(entry);
}
// Remove process record entry.
RtlDeleteElementGenericTable(&gProcessTable,
pProcessRecord);
}
else
KdPrint((“BFILTER: Process not registered.\n”));
KeReleaseSpinLock(&gProcessTableSpinLock, oldIrql);
return (ntStatus);
}

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Vladimir
Chtchetkine
Sent: Tuesday, February 24, 2004 10:03 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] RtlGenericTable

Hi everyone!

I have some set of data stored in RtlGenericTable and at some point I
need to go through all its entries and delete some of them. What would
be the best way to do it, so I can safely delete some entries and still
be able to go through remaining ones without having to restart enum? DDK
is a bit confusing on that.

TIA,

Vladimir


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as:
xxxxx@borland.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as:
xxxxx@borland.com
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com