Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

handle.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 handle.c 00008 00009 Abstract: 00010 00011 This module contains a simple handle allocator for use by the Local and 00012 Global memory allocators. 00013 00014 Author: 00015 00016 Steve Wood (stevewo) 25-Jul-1991 00017 00018 Revision History: 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 // Remove handle table entry from head of free list. 00138 // 00139 00140 p = HandleTable->FreeHandles; 00141 HandleTable->FreeHandles = p->NextFree; 00142 00143 // 00144 // Clear free list link field, which also leaves the handle allocated bit 00145 // clear. This allows the caller to mark it is allocated after they are 00146 // done filling in their portion. 00147 // 00148 00149 p->NextFree = NULL; 00150 00151 00152 // 00153 // If requested, return the index of this handle table entry 00154 // 00155 if (ARGUMENT_PRESENT( HandleIndex )) { 00156 *HandleIndex = (ULONG) (((PCHAR)p - (PCHAR)HandleTable->CommittedHandles) / 00157 HandleTable->SizeOfHandleTableEntry); 00158 } 00159 00160 // 00161 // Return a pointer to the handle table entry. 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 }

Generated on Sat May 15 19:40:14 2004 for test by doxygen 1.3.7