Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlibsupp.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS NT User-Mode DLL 00004 * FILE: lib/ntdll/rtl/libsup.c 00005 * PURPOSE: RTL Support Routines 00006 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) 00007 * Gunnar Dalsnes 00008 */ 00009 00010 /* INCLUDES *****************************************************************/ 00011 00012 #include <ntdll.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 SIZE_T RtlpAllocDeallocQueryBufferSize = PAGE_SIZE; 00017 PTEB LdrpTopLevelDllBeingLoadedTeb = NULL; 00018 00019 /* FUNCTIONS ***************************************************************/ 00020 00021 #ifndef _M_AMD64 00022 // FIXME: Why "Not implemented"??? 00023 /* 00024 * @implemented 00025 */ 00026 ULONG 00027 NTAPI 00028 RtlWalkFrameChain(OUT PVOID *Callers, 00029 IN ULONG Count, 00030 IN ULONG Flags) 00031 { 00032 /* Not implemented for user-mode */ 00033 return 0; 00034 } 00035 #endif 00036 00037 BOOLEAN 00038 NTAPI 00039 RtlpCheckForActiveDebugger(VOID) 00040 { 00041 /* Return the flag in the PEB */ 00042 return NtCurrentPeb()->BeingDebugged; 00043 } 00044 00045 BOOLEAN 00046 NTAPI 00047 RtlpSetInDbgPrint(VOID) 00048 { 00049 /* Check if it's already set and return TRUE if so */ 00050 if (NtCurrentTeb()->InDbgPrint) return TRUE; 00051 00052 /* Set it and return */ 00053 NtCurrentTeb()->InDbgPrint = TRUE; 00054 return FALSE; 00055 } 00056 00057 VOID 00058 NTAPI 00059 RtlpClearInDbgPrint(VOID) 00060 { 00061 /* Clear the flag */ 00062 NtCurrentTeb()->InDbgPrint = FALSE; 00063 } 00064 00065 KPROCESSOR_MODE 00066 NTAPI 00067 RtlpGetMode() 00068 { 00069 return UserMode; 00070 } 00071 00072 /* 00073 * @implemented 00074 */ 00075 PPEB 00076 NTAPI 00077 RtlGetCurrentPeb(VOID) 00078 { 00079 return NtCurrentPeb(); 00080 } 00081 00082 /* 00083 * @implemented 00084 */ 00085 VOID NTAPI 00086 RtlAcquirePebLock(VOID) 00087 { 00088 PPEB Peb = NtCurrentPeb (); 00089 RtlEnterCriticalSection(Peb->FastPebLock); 00090 } 00091 00092 /* 00093 * @implemented 00094 */ 00095 VOID NTAPI 00096 RtlReleasePebLock(VOID) 00097 { 00098 PPEB Peb = NtCurrentPeb (); 00099 RtlLeaveCriticalSection(Peb->FastPebLock); 00100 } 00101 00102 /* 00103 * @implemented 00104 */ 00105 ULONG 00106 NTAPI 00107 RtlGetNtGlobalFlags(VOID) 00108 { 00109 PPEB pPeb = NtCurrentPeb(); 00110 return pPeb->NtGlobalFlag; 00111 } 00112 00113 NTSTATUS 00114 NTAPI 00115 RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock) 00116 { 00117 return RtlDeleteCriticalSection(&Lock->CriticalSection); 00118 } 00119 00120 NTSTATUS 00121 NTAPI 00122 RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive) 00123 { 00124 UNREFERENCED_PARAMETER(Exclusive); 00125 00126 return RtlEnterCriticalSection(&Lock->CriticalSection); 00127 } 00128 00129 NTSTATUS 00130 NTAPI 00131 RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock) 00132 { 00133 return RtlInitializeCriticalSection(&(*Lock)->CriticalSection); 00134 } 00135 00136 NTSTATUS 00137 NTAPI 00138 RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock) 00139 { 00140 return RtlLeaveCriticalSection(&Lock->CriticalSection); 00141 } 00142 00143 PVOID 00144 NTAPI 00145 RtlpAllocateMemory(UINT Bytes, 00146 ULONG Tag) 00147 { 00148 UNREFERENCED_PARAMETER(Tag); 00149 00150 return RtlAllocateHeap(RtlGetProcessHeap(), 00151 0, 00152 Bytes); 00153 } 00154 00155 00156 VOID 00157 NTAPI 00158 RtlpFreeMemory(PVOID Mem, 00159 ULONG Tag) 00160 { 00161 UNREFERENCED_PARAMETER(Tag); 00162 00163 RtlFreeHeap(RtlGetProcessHeap(), 00164 0, 00165 Mem); 00166 } 00167 00168 00169 #if DBG 00170 VOID FASTCALL 00171 CHECK_PAGED_CODE_RTL(char *file, int line) 00172 { 00173 /* meaningless in user mode */ 00174 } 00175 #endif 00176 00177 BOOLEAN 00178 NTAPI 00179 RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, 00180 IN ULONG_PTR RegistrationFrameEnd, 00181 IN OUT PULONG_PTR StackLow, 00182 IN OUT PULONG_PTR StackHigh) 00183 { 00184 /* There's no such thing as a DPC stack in user-mode */ 00185 return FALSE; 00186 } 00187 00188 VOID 00189 NTAPI 00190 RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord, 00191 IN PCONTEXT ContextRecord, 00192 IN PVOID ContextData, 00193 IN ULONG Size) 00194 { 00195 /* Exception logging is not done in user-mode */ 00196 } 00197 00198 BOOLEAN 00199 NTAPI 00200 RtlpCaptureStackLimits(IN ULONG_PTR Ebp, 00201 IN ULONG_PTR *StackBegin, 00202 IN ULONG_PTR *StackEnd) 00203 { 00204 /* FIXME: Verify */ 00205 *StackBegin = (ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit; 00206 *StackEnd = (ULONG_PTR)NtCurrentTeb()->NtTib.StackBase; 00207 return TRUE; 00208 } 00209 00210 #ifdef _AMD64_ 00211 VOID 00212 NTAPI 00213 RtlpGetStackLimits( 00214 OUT PULONG_PTR LowLimit, 00215 OUT PULONG_PTR HighLimit) 00216 { 00217 *LowLimit = (ULONG_PTR)NtCurrentTeb()->NtTib.StackLimit; 00218 *HighLimit = (ULONG_PTR)NtCurrentTeb()->NtTib.StackBase; 00219 return; 00220 } 00221 #endif 00222 00223 BOOLEAN 00224 NTAPI 00225 RtlIsThreadWithinLoaderCallout(VOID) 00226 { 00227 return LdrpTopLevelDllBeingLoadedTeb == NtCurrentTeb(); 00228 } 00229 00230 /* RTL Atom Tables ************************************************************/ 00231 00232 typedef struct _RTL_ATOM_HANDLE 00233 { 00234 RTL_HANDLE_TABLE_ENTRY Handle; 00235 PRTL_ATOM_TABLE_ENTRY AtomEntry; 00236 } RTL_ATOM_HANDLE, *PRTL_ATOM_HANDLE; 00237 00238 NTSTATUS 00239 RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable) 00240 { 00241 RtlInitializeCriticalSection(&AtomTable->CriticalSection); 00242 return STATUS_SUCCESS; 00243 } 00244 00245 00246 VOID 00247 RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable) 00248 { 00249 RtlDeleteCriticalSection(&AtomTable->CriticalSection); 00250 } 00251 00252 00253 BOOLEAN 00254 RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable) 00255 { 00256 RtlEnterCriticalSection(&AtomTable->CriticalSection); 00257 return TRUE; 00258 } 00259 00260 00261 VOID 00262 RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable) 00263 { 00264 RtlLeaveCriticalSection(&AtomTable->CriticalSection); 00265 } 00266 00267 00268 /* handle functions */ 00269 00270 BOOLEAN 00271 RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable) 00272 { 00273 RtlInitializeHandleTable(0xCFFF, 00274 sizeof(RTL_ATOM_HANDLE), 00275 &AtomTable->RtlHandleTable); 00276 00277 return TRUE; 00278 } 00279 00280 VOID 00281 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable) 00282 { 00283 RtlDestroyHandleTable(&AtomTable->RtlHandleTable); 00284 } 00285 00286 PRTL_ATOM_TABLE 00287 RtlpAllocAtomTable(ULONG Size) 00288 { 00289 return (PRTL_ATOM_TABLE)RtlAllocateHeap(RtlGetProcessHeap(), 00290 HEAP_ZERO_MEMORY, 00291 Size); 00292 } 00293 00294 VOID 00295 RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable) 00296 { 00297 RtlFreeHeap(RtlGetProcessHeap(), 00298 0, 00299 AtomTable); 00300 } 00301 00302 PRTL_ATOM_TABLE_ENTRY 00303 RtlpAllocAtomTableEntry(ULONG Size) 00304 { 00305 return (PRTL_ATOM_TABLE_ENTRY)RtlAllocateHeap(RtlGetProcessHeap(), 00306 HEAP_ZERO_MEMORY, 00307 Size); 00308 } 00309 00310 VOID 00311 RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry) 00312 { 00313 RtlFreeHeap(RtlGetProcessHeap(), 00314 0, 00315 Entry); 00316 } 00317 00318 VOID 00319 RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry) 00320 { 00321 PRTL_HANDLE_TABLE_ENTRY RtlHandleEntry; 00322 00323 if (RtlIsValidIndexHandle(&AtomTable->RtlHandleTable, 00324 (ULONG)Entry->HandleIndex, 00325 &RtlHandleEntry)) 00326 { 00327 RtlFreeHandle(&AtomTable->RtlHandleTable, 00328 RtlHandleEntry); 00329 } 00330 } 00331 00332 BOOLEAN 00333 RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry) 00334 { 00335 ULONG HandleIndex; 00336 PRTL_HANDLE_TABLE_ENTRY RtlHandle; 00337 00338 RtlHandle = RtlAllocateHandle(&AtomTable->RtlHandleTable, 00339 &HandleIndex); 00340 if (RtlHandle != NULL) 00341 { 00342 PRTL_ATOM_HANDLE AtomHandle = (PRTL_ATOM_HANDLE)RtlHandle; 00343 00344 /* FIXME - Handle Indexes >= 0xC000 ?! */ 00345 if (HandleIndex < 0xC000) 00346 { 00347 Entry->HandleIndex = (USHORT)HandleIndex; 00348 Entry->Atom = 0xC000 + (USHORT)HandleIndex; 00349 00350 AtomHandle->AtomEntry = Entry; 00351 AtomHandle->Handle.Flags = RTL_HANDLE_VALID; 00352 00353 return TRUE; 00354 } 00355 else 00356 { 00357 /* set the valid flag, otherwise RtlFreeHandle will fail! */ 00358 AtomHandle->Handle.Flags = RTL_HANDLE_VALID; 00359 00360 RtlFreeHandle(&AtomTable->RtlHandleTable, 00361 RtlHandle); 00362 } 00363 } 00364 00365 return FALSE; 00366 } 00367 00368 PRTL_ATOM_TABLE_ENTRY 00369 RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index) 00370 { 00371 PRTL_HANDLE_TABLE_ENTRY RtlHandle; 00372 00373 if (RtlIsValidIndexHandle(&AtomTable->RtlHandleTable, 00374 Index, 00375 &RtlHandle)) 00376 { 00377 PRTL_ATOM_HANDLE AtomHandle = (PRTL_ATOM_HANDLE)RtlHandle; 00378 00379 return AtomHandle->AtomEntry; 00380 } 00381 00382 return NULL; 00383 } 00384 00385 00386 /* 00387 * Ldr Resource support code 00388 */ 00389 00390 IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir, 00391 LPCWSTR name, void *root, 00392 int want_dir ); 00393 IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir, 00394 WORD id, void *root, int want_dir ); 00395 IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir, 00396 void *root, int want_dir ); 00397 int push_language( USHORT *list, ULONG pos, WORD lang ); 00398 00399 /********************************************************************** 00400 * find_entry 00401 * 00402 * Find a resource entry 00403 */ 00404 NTSTATUS find_entry( PVOID BaseAddress, LDR_RESOURCE_INFO *info, 00405 ULONG level, void **ret, int want_dir ) 00406 { 00407 ULONG size; 00408 void *root; 00409 IMAGE_RESOURCE_DIRECTORY *resdirptr; 00410 USHORT list[9]; /* list of languages to try */ 00411 int i, pos = 0; 00412 LCID user_lcid, system_lcid; 00413 00414 root = RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size ); 00415 if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND; 00416 resdirptr = root; 00417 00418 if (!level--) goto done; 00419 if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Type, root, want_dir || level ))) 00420 return STATUS_RESOURCE_TYPE_NOT_FOUND; 00421 if (!level--) return STATUS_SUCCESS; 00422 00423 resdirptr = *ret; 00424 if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Name, root, want_dir || level ))) 00425 return STATUS_RESOURCE_NAME_NOT_FOUND; 00426 if (!level--) return STATUS_SUCCESS; 00427 if (level) return STATUS_INVALID_PARAMETER; /* level > 3 */ 00428 00429 /* 1. specified language */ 00430 pos = push_language( list, pos, info->Language ); 00431 00432 /* 2. specified language with neutral sublanguage */ 00433 pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(info->Language), SUBLANG_NEUTRAL ) ); 00434 00435 /* 3. neutral language with neutral sublanguage */ 00436 pos = push_language( list, pos, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) ); 00437 00438 /* if no explicitly specified language, try some defaults */ 00439 if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL) 00440 { 00441 /* user defaults, unless SYS_DEFAULT sublanguage specified */ 00442 if (SUBLANGID(info->Language) != SUBLANG_SYS_DEFAULT) 00443 { 00444 /* 4. current thread locale language */ 00445 pos = push_language( list, pos, LANGIDFROMLCID(NtCurrentTeb()->CurrentLocale) ); 00446 00447 if (NT_SUCCESS(NtQueryDefaultLocale(TRUE, &user_lcid))) 00448 { 00449 /* 5. user locale language */ 00450 pos = push_language( list, pos, LANGIDFROMLCID(user_lcid) ); 00451 00452 /* 6. user locale language with neutral sublanguage */ 00453 pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(user_lcid), SUBLANG_NEUTRAL ) ); 00454 } 00455 } 00456 00457 /* now system defaults */ 00458 00459 if (NT_SUCCESS(NtQueryDefaultLocale(FALSE, &system_lcid))) 00460 { 00461 /* 7. system locale language */ 00462 pos = push_language( list, pos, LANGIDFROMLCID( system_lcid ) ); 00463 00464 /* 8. system locale language with neutral sublanguage */ 00465 pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(system_lcid), SUBLANG_NEUTRAL ) ); 00466 } 00467 00468 /* 9. English */ 00469 pos = push_language( list, pos, MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) ); 00470 } 00471 00472 resdirptr = *ret; 00473 for (i = 0; i < pos; i++) 00474 if ((*ret = find_entry_by_id( resdirptr, list[i], root, want_dir ))) return STATUS_SUCCESS; 00475 00476 /* if no explicitly specified language, return the first entry */ 00477 if (PRIMARYLANGID(info->Language) == LANG_NEUTRAL) 00478 { 00479 if ((*ret = find_first_entry( resdirptr, root, want_dir ))) return STATUS_SUCCESS; 00480 } 00481 return STATUS_RESOURCE_LANG_NOT_FOUND; 00482 00483 done: 00484 *ret = resdirptr; 00485 return STATUS_SUCCESS; 00486 } 00487 00488 /* 00489 * @implemented 00490 */ 00491 PVOID NTAPI 00492 RtlPcToFileHeader(IN PVOID PcValue, 00493 PVOID* BaseOfImage) 00494 { 00495 PLIST_ENTRY ModuleListHead; 00496 PLIST_ENTRY Entry; 00497 PLDR_DATA_TABLE_ENTRY Module; 00498 PVOID ImageBase = NULL; 00499 00500 RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); 00501 ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList; 00502 Entry = ModuleListHead->Flink; 00503 while (Entry != ModuleListHead) 00504 { 00505 Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 00506 00507 if ((ULONG_PTR)PcValue >= (ULONG_PTR)Module->DllBase && 00508 (ULONG_PTR)PcValue < (ULONG_PTR)Module->DllBase + Module->SizeOfImage) 00509 { 00510 ImageBase = Module->DllBase; 00511 break; 00512 } 00513 Entry = Entry->Flink; 00514 } 00515 RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); 00516 00517 *BaseOfImage = ImageBase; 00518 return ImageBase; 00519 } 00520 00521 /* 00522 * @unimplemented 00523 */ 00524 NTSYSAPI 00525 NTSTATUS 00526 NTAPI 00527 RtlDosApplyFileIsolationRedirection_Ustr(IN ULONG Flags, 00528 IN PUNICODE_STRING OriginalName, 00529 IN PUNICODE_STRING Extension, 00530 IN OUT PUNICODE_STRING StaticString, 00531 IN OUT PUNICODE_STRING DynamicString, 00532 IN OUT PUNICODE_STRING *NewName, 00533 IN PULONG NewFlags, 00534 IN PSIZE_T FileNameSize, 00535 IN PSIZE_T RequiredLength) 00536 { 00537 return STATUS_SXS_KEY_NOT_FOUND; 00538 } 00539 00540 /* 00541 * @implemented 00542 */ 00543 NTSYSAPI 00544 NTSTATUS 00545 NTAPI 00546 RtlWow64EnableFsRedirection(IN BOOLEAN Wow64FsEnableRedirection) 00547 { 00548 /* This is what Windows returns on x86 */ 00549 return STATUS_NOT_IMPLEMENTED; 00550 } 00551 00552 /* 00553 * @implemented 00554 */ 00555 NTSYSAPI 00556 NTSTATUS 00557 NTAPI 00558 RtlWow64EnableFsRedirectionEx(IN PVOID Wow64FsEnableRedirection, 00559 OUT PVOID *OldFsRedirectionLevel) 00560 { 00561 /* This is what Windows returns on x86 */ 00562 return STATUS_NOT_IMPLEMENTED; 00563 } 00564 00565 /* 00566 * @unimplemented 00567 */ 00568 NTSYSAPI 00569 NTSTATUS 00570 NTAPI 00571 RtlComputeImportTableHash(IN HANDLE FileHandle, 00572 OUT PCHAR Hash, 00573 IN ULONG ImporTTableHashSize) 00574 { 00575 UNIMPLEMENTED; 00576 return STATUS_NOT_IMPLEMENTED; 00577 } 00578 00579 /* EOF */ Generated on Sun May 27 2012 04:19:17 for ReactOS by
1.7.6.1
|