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 kernel
00004  * FILE:            ntoskrnl/rtl/libsupp.c
00005  * PURPOSE:         RTL Support Routines
00006  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
00007  *                  Gunnar Dalsnes
00008  */
00009 
00010 /* INCLUDES ******************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 #define TAG_ATMT 'TotA' /* Atom table */
00017 
00018 extern ULONG NtGlobalFlag;
00019 
00020 typedef struct _RTL_RANGE_ENTRY
00021 {
00022     LIST_ENTRY Entry;
00023     RTL_RANGE Range;
00024 } RTL_RANGE_ENTRY, *PRTL_RANGE_ENTRY;
00025 
00026 PAGED_LOOKASIDE_LIST RtlpRangeListEntryLookasideList;
00027 SIZE_T RtlpAllocDeallocQueryBufferSize = 128;
00028 
00029 /* FUNCTIONS *****************************************************************/
00030 
00031 PVOID
00032 NTAPI
00033 RtlPcToFileHeader(
00034     IN  PVOID PcValue,
00035     OUT PVOID *BaseOfImage)
00036 {
00037     PLDR_DATA_TABLE_ENTRY LdrEntry;
00038     BOOLEAN InSystem;
00039 
00040     /* Get the base for this file */
00041     if ((ULONG_PTR)PcValue > (ULONG_PTR)MmHighestUserAddress)
00042     {
00043         /* We are in kernel */
00044         *BaseOfImage = KiPcToFileHeader(PcValue, &LdrEntry, FALSE, &InSystem);
00045     }
00046     else
00047     {
00048         /* We are in user land */
00049         *BaseOfImage = KiRosPcToUserFileHeader(PcValue, &LdrEntry);
00050     }
00051 
00052     return *BaseOfImage;
00053 }
00054 
00055 VOID
00056 NTAPI
00057 RtlInitializeRangeListPackage(VOID)
00058 {
00059     /* Setup the lookaside list for allocations (not used yet) */
00060     ExInitializePagedLookasideList(&RtlpRangeListEntryLookasideList,
00061                                    NULL,
00062                                    NULL,
00063                                    POOL_COLD_ALLOCATION,
00064                                    sizeof(RTL_RANGE_ENTRY),
00065                                    'elRR',
00066                                    16);
00067 }
00068 
00069 BOOLEAN
00070 NTAPI
00071 RtlpCheckForActiveDebugger(VOID)
00072 {
00073     /* This check is meaningless in kernel-mode */
00074     return FALSE;
00075 }
00076 
00077 BOOLEAN
00078 NTAPI
00079 RtlpSetInDbgPrint(VOID)
00080 {
00081     /* Nothing to set in kernel mode */
00082     return FALSE;
00083 }
00084 
00085 VOID
00086 NTAPI
00087 RtlpClearInDbgPrint(VOID)
00088 {
00089     /* Nothing to clear in kernel mode */
00090 }
00091 
00092 KPROCESSOR_MODE
00093 NTAPI
00094 RtlpGetMode()
00095 {
00096    return KernelMode;
00097 }
00098 
00099 PVOID
00100 NTAPI
00101 RtlpAllocateMemory(ULONG Bytes,
00102                    ULONG Tag)
00103 {
00104     return ExAllocatePoolWithTag(PagedPool,
00105                                  (SIZE_T)Bytes,
00106                                  Tag);
00107 }
00108 
00109 
00110 #define TAG_USTR        'RTSU'
00111 #define TAG_ASTR        'RTSA'
00112 #define TAG_OSTR        'RTSO'
00113 VOID
00114 NTAPI
00115 RtlpFreeMemory(PVOID Mem,
00116                ULONG Tag)
00117 {
00118     if (Tag == TAG_ASTR || Tag == TAG_OSTR || Tag == TAG_USTR)
00119         ExFreePool(Mem);
00120     else
00121         ExFreePoolWithTag(Mem, Tag);
00122 }
00123 
00124 /*
00125  * @implemented
00126  */
00127 VOID NTAPI
00128 RtlAcquirePebLock(VOID)
00129 {
00130 
00131 }
00132 
00133 /*
00134  * @implemented
00135  */
00136 VOID NTAPI
00137 RtlReleasePebLock(VOID)
00138 {
00139 
00140 }
00141 
00142 NTSTATUS
00143 NTAPI
00144 LdrShutdownThread(VOID)
00145 {
00146     return STATUS_SUCCESS;
00147 }
00148 
00149 
00150 PPEB
00151 NTAPI
00152 RtlGetCurrentPeb(VOID)
00153 {
00154    return ((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->Peb;
00155 }
00156 
00157 NTSTATUS
00158 NTAPI
00159 RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
00160 {
00161     ExDeleteResourceLite(&Lock->Resource);
00162     ExFreePool(Lock);
00163 
00164     return STATUS_SUCCESS;
00165 }
00166 
00167 NTSTATUS
00168 NTAPI
00169 RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
00170 {
00171     KeEnterCriticalRegion();
00172 
00173     if (Exclusive)
00174         ExAcquireResourceExclusiveLite(&Lock->Resource, TRUE);
00175     else
00176         ExAcquireResourceSharedLite(&Lock->Resource, TRUE);
00177 
00178     return STATUS_SUCCESS;
00179 }
00180 
00181 NTSTATUS
00182 NTAPI
00183 RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
00184 {
00185     PHEAP_LOCK HeapLock = ExAllocatePool(NonPagedPool, sizeof(HEAP_LOCK));
00186     if (HeapLock == NULL)
00187         return STATUS_NO_MEMORY;
00188 
00189     ExInitializeResourceLite(&HeapLock->Resource);
00190     *Lock = HeapLock;
00191 
00192     return STATUS_SUCCESS;
00193 }
00194 
00195 NTSTATUS
00196 NTAPI
00197 RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
00198 {
00199     ExReleaseResourceLite(&Lock->Resource);
00200     KeLeaveCriticalRegion();
00201 
00202     return STATUS_SUCCESS;
00203 }
00204 
00205 #if DBG
00206 VOID FASTCALL
00207 CHECK_PAGED_CODE_RTL(char *file, int line)
00208 {
00209   if(KeGetCurrentIrql() > APC_LEVEL)
00210   {
00211     DbgPrint("%s:%i: Pagable code called at IRQL > APC_LEVEL (%d)\n", file, line, KeGetCurrentIrql());
00212     ASSERT(FALSE);
00213   }
00214 }
00215 #endif
00216 
00217 VOID
00218 NTAPI
00219 RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord,
00220                       IN PCONTEXT ContextRecord,
00221                       IN PVOID ContextData,
00222                       IN ULONG Size)
00223 {
00224     /* Check the global flag */
00225     if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING)
00226     {
00227         /* FIXME: Log this exception */
00228     }
00229 }
00230 
00231 BOOLEAN
00232 NTAPI
00233 RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
00234                             IN ULONG_PTR RegistrationFrameEnd,
00235                             IN OUT PULONG_PTR StackLow,
00236                             IN OUT PULONG_PTR StackHigh)
00237 {
00238     PKPRCB Prcb;
00239     ULONG_PTR DpcStack;
00240 
00241     /* Check if we are at DISPATCH or higher */
00242     if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
00243     {
00244         /* Get the PRCB and DPC Stack */
00245         Prcb = KeGetCurrentPrcb();
00246         DpcStack = (ULONG_PTR)Prcb->DpcStack;
00247 
00248         /* Check if we are in a DPC and the stack matches */
00249         if ((Prcb->DpcRoutineActive) &&
00250             (RegistrationFrameEnd <= DpcStack) &&
00251             ((ULONG_PTR)RegistrationFrame >= DpcStack - KERNEL_STACK_SIZE))
00252         {
00253             /* Update the limits to the DPC Stack's */
00254             *StackHigh = DpcStack;
00255             *StackLow = DpcStack - KERNEL_STACK_SIZE;
00256             return TRUE;
00257         }
00258     }
00259 
00260     /* Not in DPC stack */
00261     return FALSE;
00262 }
00263 
00264 #if !defined(_ARM_) && !defined(_AMD64_)
00265 
00266 BOOLEAN
00267 NTAPI
00268 RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
00269                        IN ULONG_PTR *StackBegin,
00270                        IN ULONG_PTR *StackEnd)
00271 {
00272     PKTHREAD Thread = KeGetCurrentThread();
00273 
00274     /* Don't even try at ISR level or later */
00275     if (KeGetCurrentIrql() > DISPATCH_LEVEL) return FALSE;
00276 
00277     /* Start with defaults */
00278     *StackBegin = Thread->StackLimit;
00279     *StackEnd = (ULONG_PTR)Thread->StackBase;
00280 
00281     /* Check if EBP is inside the stack */
00282     if ((*StackBegin <= Ebp) && (Ebp <= *StackEnd))
00283     {
00284         /* Then make the stack start at EBP */
00285         *StackBegin = Ebp;
00286     }
00287     else
00288     {
00289         /* Now we're going to assume we're on the DPC stack */
00290         *StackEnd = (ULONG_PTR)(KeGetPcr()->Prcb->DpcStack);
00291         *StackBegin = *StackEnd - KERNEL_STACK_SIZE;
00292 
00293         /* Check if we seem to be on the DPC stack */
00294         if ((*StackEnd) && (*StackBegin < Ebp) && (Ebp <= *StackEnd))
00295         {
00296             /* We're on the DPC stack */
00297             *StackBegin = Ebp;
00298         }
00299         else
00300         {
00301             /* We're somewhere else entirely... use EBP for safety */
00302             *StackBegin = Ebp;
00303             *StackEnd = (ULONG_PTR)PAGE_ALIGN(*StackBegin);
00304         }
00305     }
00306 
00307     /* Return success */
00308     return TRUE;
00309 }
00310 
00311 /*
00312  * @implemented
00313  */
00314 ULONG
00315 NTAPI
00316 RtlWalkFrameChain(OUT PVOID *Callers,
00317                   IN ULONG Count,
00318                   IN ULONG Flags)
00319 {
00320     ULONG_PTR Stack, NewStack, StackBegin, StackEnd = 0;
00321     ULONG Eip;
00322     BOOLEAN Result, StopSearch = FALSE;
00323     ULONG i = 0;
00324     PETHREAD Thread = PsGetCurrentThread();
00325     PTEB Teb;
00326     PKTRAP_FRAME TrapFrame;
00327 
00328     /* Get current EBP */
00329 #if defined(_M_IX86)
00330 #if defined __GNUC__
00331     __asm__("mov %%ebp, %0" : "=r" (Stack) : );
00332 #elif defined(_MSC_VER)
00333     __asm mov Stack, ebp
00334 #endif
00335 #elif defined(_M_MIPS)
00336         __asm__("move $sp, %0" : "=r" (Stack) : );
00337 #elif defined(_M_PPC)
00338     __asm__("mr %0,1" : "=r" (Stack) : );
00339 #elif defined(_M_ARM)
00340     __asm__("mov sp, %0" : "=r"(Stack) : );
00341 #else
00342 #error Unknown architecture
00343 #endif
00344 
00345     /* Set it as the stack begin limit as well */
00346     StackBegin = (ULONG_PTR)Stack;
00347 
00348     /* Check if we're called for non-logging mode */
00349     if (!Flags)
00350     {
00351         /* Get the actual safe limits */
00352         Result = RtlpCaptureStackLimits((ULONG_PTR)Stack,
00353                                         &StackBegin,
00354                                         &StackEnd);
00355         if (!Result) return 0;
00356         }
00357 
00358     /* Use a SEH block for maximum protection */
00359     _SEH2_TRY
00360     {
00361         /* Check if we want the user-mode stack frame */
00362         if (Flags == 1)
00363         {
00364             /* Get the trap frame and TEB */
00365             TrapFrame = KeGetTrapFrame(&Thread->Tcb);
00366             Teb = Thread->Tcb.Teb;
00367 
00368             /* Make sure we can trust the TEB and trap frame */
00369             if (!(Teb) ||
00370                 (KeIsAttachedProcess()) ||
00371                 (KeGetCurrentIrql() >= DISPATCH_LEVEL))
00372             {
00373                 /* Invalid or unsafe attempt to get the stack */
00374                 _SEH2_YIELD(return 0;)
00375             }
00376 
00377             /* Get the stack limits */
00378             StackBegin = (ULONG_PTR)Teb->NtTib.StackLimit;
00379             StackEnd = (ULONG_PTR)Teb->NtTib.StackBase;
00380 #ifdef _M_IX86
00381             Stack = TrapFrame->Ebp;
00382 #elif defined(_M_PPC)
00383             Stack = TrapFrame->Gpr1;
00384 #else
00385 #error Unknown architecture
00386 #endif
00387 
00388             /* Validate them */
00389             if (StackEnd <= StackBegin) return 0;
00390             ProbeForRead((PVOID)StackBegin,
00391                          StackEnd - StackBegin,
00392                          sizeof(CHAR));
00393         }
00394 
00395         /* Loop the frames */
00396         for (i = 0; i < Count; i++)
00397         {
00398             /*
00399              * Leave if we're past the stack,
00400              * if we're before the stack,
00401              * or if we've reached ourselves.
00402              */
00403             if ((Stack >= StackEnd) ||
00404                 (!i ? (Stack < StackBegin) : (Stack <= StackBegin)) ||
00405                 ((StackEnd - Stack) < (2 * sizeof(ULONG_PTR))))
00406             {
00407                 /* We're done or hit a bad address */
00408                 break;
00409             }
00410 
00411             /* Get new stack and EIP */
00412             NewStack = *(PULONG_PTR)Stack;
00413             Eip = *(PULONG_PTR)(Stack + sizeof(ULONG_PTR));
00414 
00415             /* Check if the new pointer is above the oldone and past the end */
00416             if (!((Stack < NewStack) && (NewStack < StackEnd)))
00417             {
00418                 /* Stop searching after this entry */
00419                 StopSearch = TRUE;
00420             }
00421 
00422             /* Also make sure that the EIP isn't a stack address */
00423             if ((StackBegin < Eip) && (Eip < StackEnd)) break;
00424 
00425             /* Check if we reached a user-mode address */
00426             if (!(Flags) && !(Eip & 0x80000000)) break; // FIXME: 3GB breakage
00427 
00428             /* Save this frame */
00429             Callers[i] = (PVOID)Eip;
00430 
00431             /* Check if we should continue */
00432             if (StopSearch)
00433             {
00434                 /* Return the next index */
00435                 i++;
00436                 break;
00437             }
00438 
00439             /* Move to the next stack */
00440             Stack = NewStack;
00441         }
00442     }
00443     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00444     {
00445         /* No index */
00446         i = 0;
00447     }
00448     _SEH2_END;
00449 
00450     /* Return frames parsed */
00451     return i;
00452 }
00453 
00454 #endif
00455 
00456 #ifdef _AMD64_
00457 VOID
00458 NTAPI
00459 RtlpGetStackLimits(
00460     OUT PULONG_PTR LowLimit,
00461     OUT PULONG_PTR HighLimit)
00462 {
00463     PKTHREAD CurrentThread = KeGetCurrentThread();
00464     *HighLimit = (ULONG_PTR)CurrentThread->InitialStack;
00465     *LowLimit = (ULONG_PTR)CurrentThread->StackLimit;
00466 }
00467 #endif
00468 
00469 /* RTL Atom Tables ************************************************************/
00470 
00471 NTSTATUS
00472 RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable)
00473 {
00474    ExInitializeFastMutex(&AtomTable->FastMutex);
00475 
00476    return STATUS_SUCCESS;
00477 }
00478 
00479 
00480 VOID
00481 RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable)
00482 {
00483 }
00484 
00485 
00486 BOOLEAN
00487 RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable)
00488 {
00489    ExAcquireFastMutex(&AtomTable->FastMutex);
00490    return TRUE;
00491 }
00492 
00493 VOID
00494 RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable)
00495 {
00496    ExReleaseFastMutex(&AtomTable->FastMutex);
00497 }
00498 
00499 BOOLEAN
00500 RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
00501 {
00502    AtomTable->ExHandleTable = ExCreateHandleTable(NULL);
00503    return (AtomTable->ExHandleTable != NULL);
00504 }
00505 
00506 VOID
00507 RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
00508 {
00509    if (AtomTable->ExHandleTable)
00510    {
00511       ExSweepHandleTable(AtomTable->ExHandleTable,
00512                          NULL,
00513                          NULL);
00514       ExDestroyHandleTable(AtomTable->ExHandleTable, NULL);
00515       AtomTable->ExHandleTable = NULL;
00516    }
00517 }
00518 
00519 PRTL_ATOM_TABLE
00520 RtlpAllocAtomTable(ULONG Size)
00521 {
00522    PRTL_ATOM_TABLE Table = ExAllocatePool(NonPagedPool,
00523                                           Size);
00524    if (Table != NULL)
00525    {
00526       RtlZeroMemory(Table,
00527                     Size);
00528    }
00529 
00530    return Table;
00531 }
00532 
00533 VOID
00534 RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable)
00535 {
00536    ExFreePool(AtomTable);
00537 }
00538 
00539 PRTL_ATOM_TABLE_ENTRY
00540 RtlpAllocAtomTableEntry(ULONG Size)
00541 {
00542     PRTL_ATOM_TABLE_ENTRY Entry;
00543 
00544     Entry = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_ATMT);
00545     if (Entry != NULL)
00546     {
00547         RtlZeroMemory(Entry, Size);
00548     }
00549 
00550     return Entry;
00551 }
00552 
00553 VOID
00554 RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry)
00555 {
00556     ExFreePoolWithTag(Entry, TAG_ATMT);
00557 }
00558 
00559 VOID
00560 RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
00561 {
00562    ExDestroyHandle(AtomTable->ExHandleTable,
00563                    (HANDLE)((ULONG_PTR)Entry->HandleIndex << 2),
00564                    NULL);
00565 }
00566 
00567 BOOLEAN
00568 RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry)
00569 {
00570    HANDLE_TABLE_ENTRY ExEntry;
00571    HANDLE Handle;
00572    USHORT HandleIndex;
00573 
00574    /* Initialize ex handle table entry */
00575    ExEntry.Object = Entry;
00576    ExEntry.GrantedAccess = 0x1; /* FIXME - valid handle */
00577 
00578    /* Create ex handle */
00579    Handle = ExCreateHandle(AtomTable->ExHandleTable,
00580                            &ExEntry);
00581    if (!Handle) return FALSE;
00582 
00583    /* Calculate HandleIndex (by getting rid of the first two bits) */
00584    HandleIndex = (USHORT)((ULONG_PTR)Handle >> 2);
00585 
00586    /* Index must be less than 0xC000 */
00587    if (HandleIndex >= 0xC000)
00588    {
00589        /* Destroy ex handle */
00590        ExDestroyHandle(AtomTable->ExHandleTable,
00591                        Handle,
00592                        NULL);
00593 
00594        /* Return failure */
00595        return FALSE;
00596    }
00597 
00598    /* Initialize atom table entry */
00599    Entry->HandleIndex = HandleIndex;
00600    Entry->Atom = 0xC000 + HandleIndex;
00601 
00602    /* Return success */
00603    return TRUE;
00604 }
00605 
00606 PRTL_ATOM_TABLE_ENTRY
00607 RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index)
00608 {
00609    PHANDLE_TABLE_ENTRY ExEntry;
00610    PRTL_ATOM_TABLE_ENTRY Entry = NULL;
00611 
00612    /* NOTE: There's no need to explicitly enter a critical region because it's
00613             guaranteed that we're in a critical region right now (as we hold
00614             the atom table lock) */
00615 
00616    ExEntry = ExMapHandleToPointer(AtomTable->ExHandleTable,
00617                                   (HANDLE)((ULONG_PTR)Index << 2));
00618    if (ExEntry != NULL)
00619    {
00620       Entry = ExEntry->Object;
00621 
00622       ExUnlockHandleTableEntry(AtomTable->ExHandleTable,
00623                                ExEntry);
00624    }
00625 
00626    return Entry;
00627 }
00628 
00629 /*
00630  * Ldr Resource support code
00631  */
00632 
00633 IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( IMAGE_RESOURCE_DIRECTORY *dir,
00634                                               LPCWSTR name, void *root,
00635                                               int want_dir );
00636 IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( IMAGE_RESOURCE_DIRECTORY *dir,
00637                                             USHORT id, void *root, int want_dir );
00638 IMAGE_RESOURCE_DIRECTORY *find_first_entry( IMAGE_RESOURCE_DIRECTORY *dir,
00639                                             void *root, int want_dir );
00640 
00641 /**********************************************************************
00642  *  find_entry
00643  *
00644  * Find a resource entry
00645  */
00646 NTSTATUS find_entry( PVOID BaseAddress, LDR_RESOURCE_INFO *info,
00647                      ULONG level, void **ret, int want_dir )
00648 {
00649     ULONG size;
00650     void *root;
00651     IMAGE_RESOURCE_DIRECTORY *resdirptr;
00652 
00653     root = RtlImageDirectoryEntryToData( BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size );
00654     if (!root) return STATUS_RESOURCE_DATA_NOT_FOUND;
00655     resdirptr = root;
00656 
00657     if (!level--) goto done;
00658     if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Type, root, want_dir || level )))
00659         return STATUS_RESOURCE_TYPE_NOT_FOUND;
00660     if (!level--) return STATUS_SUCCESS;
00661 
00662     resdirptr = *ret;
00663     if (!(*ret = find_entry_by_name( resdirptr, (LPCWSTR)info->Name, root, want_dir || level )))
00664         return STATUS_RESOURCE_NAME_NOT_FOUND;
00665     if (!level--) return STATUS_SUCCESS;
00666     if (level) return STATUS_INVALID_PARAMETER;  /* level > 3 */
00667 
00668     resdirptr = *ret;
00669 
00670     if ((*ret = find_first_entry( resdirptr, root, want_dir ))) return STATUS_SUCCESS;
00671 
00672     return STATUS_RESOURCE_DATA_NOT_FOUND;
00673 
00674 done:
00675     *ret = resdirptr;
00676     return STATUS_SUCCESS;
00677 }
00678 
00679 
00680 /* EOF */

Generated on Fri May 25 2012 04:17:23 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.