00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "ntrtlp.h"
00023
00024
void
00025 RtlInitializeHandleTable(
00026 IN ULONG MaximumNumberOfHandles,
00027 IN ULONG SizeOfHandleTableEntry,
00028 OUT PRTL_HANDLE_TABLE HandleTable
00029 )
00030 {
00031 RtlZeroMemory( HandleTable,
sizeof( *HandleTable ) );
00032 HandleTable->MaximumNumberOfHandles = MaximumNumberOfHandles;
00033 HandleTable->SizeOfHandleTableEntry = SizeOfHandleTableEntry;
00034
00035
return;
00036 }
00037
00038
NTSTATUS
00039 RtlDestroyHandleTable(
00040 IN OUT PRTL_HANDLE_TABLE HandleTable
00041 )
00042 {
00043
NTSTATUS Status;
00044 PVOID BaseAddress;
00045 SIZE_T ReserveSize;
00046
00047 BaseAddress = HandleTable->CommittedHandles;
00048 ReserveSize = (PUCHAR)(HandleTable->MaxReservedHandles) -
00049 (PUCHAR)(HandleTable->CommittedHandles);
00050
00051
Status =
NtFreeVirtualMemory( NtCurrentProcess(),
00052 &BaseAddress,
00053 &ReserveSize,
00054 MEM_RELEASE
00055 );
00056
return Status;
00057 }
00058
00059 PRTL_HANDLE_TABLE_ENTRY
00060 RtlAllocateHandle(
00061 IN PRTL_HANDLE_TABLE HandleTable,
00062 OUT PULONG HandleIndex OPTIONAL
00063 )
00064 {
00065
NTSTATUS Status;
00066 PVOID BaseAddress;
00067 ULONG
n;
00068 SIZE_T ReserveSize;
00069 SIZE_T CommitSize;
00070 PRTL_HANDLE_TABLE_ENTRY p, *pp;
00071
00072
if (HandleTable->FreeHandles ==
NULL) {
00073
try {
00074
if (HandleTable->UnCommittedHandles ==
NULL) {
00075 ReserveSize = HandleTable->MaximumNumberOfHandles *
00076 HandleTable->SizeOfHandleTableEntry;
00077 BaseAddress =
NULL;
00078
Status =
NtAllocateVirtualMemory( NtCurrentProcess(),
00079 &BaseAddress,
00080 0,
00081 &ReserveSize,
00082 MEM_RESERVE,
00083 PAGE_READWRITE
00084 );
00085
00086
if (
NT_SUCCESS(
Status )) {
00087 HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)BaseAddress;
00088 HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)BaseAddress;
00089 HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)
00090 ((PCHAR)BaseAddress + ReserveSize);
00091 }
00092 }
00093
else {
00094
Status = STATUS_SUCCESS;
00095 }
00096
00097
00098
if (
NT_SUCCESS(
Status )) {
00099 p = HandleTable->UnCommittedHandles;
00100
if (p >= HandleTable->MaxReservedHandles) {
00101
Status = STATUS_NO_MEMORY;
00102 }
00103
else {
00104 CommitSize =
PAGE_SIZE;
00105
Status =
NtAllocateVirtualMemory( NtCurrentProcess(),
00106 (PVOID *)&p,
00107 0,
00108 &CommitSize,
00109 MEM_COMMIT,
00110 PAGE_READWRITE
00111 );
00112
if (
NT_SUCCESS(
Status )) {
00113 HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)
00114 ((PCH)p + CommitSize);
00115 }
00116 }
00117 }
00118
00119 }
00120 except(
EXCEPTION_EXECUTE_HANDLER ) {
00121
Status = GetExceptionCode();
00122 }
00123
00124
if (!
NT_SUCCESS(
Status )) {
00125
return NULL;
00126 }
00127
00128 pp = &HandleTable->FreeHandles;
00129
while (p < HandleTable->UnCommittedHandles) {
00130 *pp = p;
00131 pp = &p->NextFree;
00132 p = (PRTL_HANDLE_TABLE_ENTRY)((PUCHAR)p + HandleTable->SizeOfHandleTableEntry);
00133 }
00134 }
00135
00136
00137
00138
00139
00140 p = HandleTable->FreeHandles;
00141 HandleTable->FreeHandles = p->NextFree;
00142
00143
00144
00145
00146
00147
00148
00149 p->NextFree =
NULL;
00150
00151
00152
00153
00154
00155
if (ARGUMENT_PRESENT( HandleIndex )) {
00156 *HandleIndex = (ULONG) (((PCHAR)p - (PCHAR)HandleTable->CommittedHandles) /
00157 HandleTable->SizeOfHandleTableEntry);
00158 }
00159
00160
00161
00162
00163
00164
return p;
00165 }
00166
00167
00168 BOOLEAN
00169 RtlFreeHandle(
00170 IN PRTL_HANDLE_TABLE HandleTable,
00171 IN PRTL_HANDLE_TABLE_ENTRY Handle
00172 )
00173 {
00174
#if DBG
00175
if (!
RtlIsValidHandle( HandleTable,
Handle )) {
00176
DbgPrint(
"RTL: RtlFreeHandle( %lx ) - invalid handle\n",
Handle );
00177
if (NtCurrentPeb()->BeingDebugged) {
00178 DbgBreakPoint();
00179 }
00180
return FALSE;
00181 }
00182
#endif
00183
00184 RtlZeroMemory(
Handle, HandleTable->SizeOfHandleTableEntry );
00185
Handle->NextFree = HandleTable->FreeHandles;
00186 HandleTable->FreeHandles =
Handle;
00187
return TRUE;
00188 }
00189
00190
00191
00192 BOOLEAN
00193 RtlIsValidHandle(
00194 IN PRTL_HANDLE_TABLE HandleTable,
00195 IN PRTL_HANDLE_TABLE_ENTRY Handle
00196 )
00197 {
00198
if (
Handle ==
NULL ||
00199
Handle < HandleTable->CommittedHandles ||
00200
Handle >= HandleTable->UnCommittedHandles ||
00201 (ULONG_PTR)
Handle & (HandleTable->SizeOfHandleTableEntry - 1) ||
00202 !(
Handle->Flags & RTL_HANDLE_ALLOCATED)
00203 ) {
00204
return FALSE;
00205 }
00206
else {
00207
return TRUE;
00208 }
00209 }
00210
00211
00212 BOOLEAN
00213 RtlIsValidIndexHandle(
00214 IN PRTL_HANDLE_TABLE HandleTable,
00215 IN ULONG HandleIndex,
00216 OUT PRTL_HANDLE_TABLE_ENTRY *Handle
00217 )
00218 {
00219 PRTL_HANDLE_TABLE_ENTRY p;
00220
00221 p = (PRTL_HANDLE_TABLE_ENTRY)
00222 ((PCHAR)HandleTable->CommittedHandles + (HandleIndex * HandleTable->SizeOfHandleTableEntry));
00223
00224
if (
RtlIsValidHandle( HandleTable, p )) {
00225 *
Handle = p;
00226
return TRUE;
00227 }
00228
else {
00229
return FALSE;
00230 }
00231 }