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 }