ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

libsupp.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.