/* * @implemented */ PVOID LoadOle32Export(PVOID * BaseAddress, const PCHAR ProcedureName) { NTSTATUS Status; ANSI_STRING ExportName; PVOID ProcedureAddress; /* First load ole32.dll */ Status = LdrLoadDll(NULL, NULL, &Old32Dll, BaseAddress); if (!NT_SUCCESS(Status)) { RtlRaiseStatus(Status); } RtlInitAnsiString(&ExportName, ProcedureName); /* Look for the procedure */ Status = LdrGetProcedureAddress(*BaseAddress, &ExportName, 0, &ProcedureAddress); if (!NT_SUCCESS(Status)) { RtlRaiseStatus(Status); } /* Return its address */ return ProcedureAddress; }
/* * @implemented */ VOID NTAPI FsRtlpPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine, IN BOOLEAN IsPaging) { PSTACK_OVERFLOW_WORK_ITEM WorkItem; /* Try to allocate a work item */ WorkItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(STACK_OVERFLOW_WORK_ITEM), 'FSrs'); if (WorkItem == NULL) { /* If we failed, and we are not a paging file, just raise an error */ if (!IsPaging) { RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); } /* Otherwise, wait for fallback workitem to be available and use it */ KeWaitForSingleObject(&StackOverflowFallbackSerialEvent, Executive, KernelMode, FALSE, NULL); WorkItem = &StackOverflowFallback; } /* Initialize work item */ WorkItem->Context = Context; WorkItem->Event = Event; WorkItem->Routine = StackOverflowRoutine; ExInitializeWorkItem(&WorkItem->WorkItem, FsRtlStackOverflowRead, WorkItem); /* And queue it in the appropriate queue (paging or not?) */ KeInsertQueue(&FsRtlWorkerQueues[IsPaging], &WorkItem->WorkItem.List); }
VOID readfile ( HANDLE handle, ULONG offset, ULONG len, PVOID buffer ) { NTSTATUS status; IO_STATUS_BLOCK iosb; LARGE_INTEGER foffset; foffset = RtlConvertUlongToLargeInteger(offset); status = NtReadFile ( handle, NULL, // event NULL, // apc routine NULL, // apc context &iosb, buffer, len, &foffset, NULL ); if (!NT_SUCCESS(status)) { RtlRaiseStatus (1); } }
/* * @implemented */ VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection) { NTSTATUS Status; /* Initialize the critical section and raise an exception if we failed */ Status = RtlInitializeCriticalSection((PVOID)lpCriticalSection); if (!NT_SUCCESS(Status)) RtlRaiseStatus(Status); }
ULONG ConvertImportAddress ( IN ULONG ImageRelativeAddress, IN ULONG PoolAddress, IN PIMAGE_SECTION_HEADER SectionHeader ) { ULONG EffectiveAddress; EffectiveAddress = PoolAddress + ImageRelativeAddress - SectionHeader->VirtualAddress; if (EffectiveAddress < PoolAddress || EffectiveAddress > PoolAddress + SectionHeader->SizeOfRawData) { RtlRaiseStatus (1); } return EffectiveAddress; }
/* * @implemented */ VOID NTAPI RtlRaiseException(IN PEXCEPTION_RECORD ExceptionRecord) { CONTEXT Context; NTSTATUS Status; /* Capture the context */ RtlCaptureContext(&Context); /* Save the exception address */ ExceptionRecord->ExceptionAddress = _ReturnAddress(); /* Write the context flag */ Context.ContextFlags = CONTEXT_FULL; /* Check if user mode debugger is active */ if (RtlpCheckForActiveDebugger()) { /* Raise an exception immediately */ Status = ZwRaiseException(ExceptionRecord, &Context, TRUE); } else { /* Dispatch the exception and check if we should continue */ if (!RtlDispatchException(ExceptionRecord, &Context)) { /* Raise the exception */ Status = ZwRaiseException(ExceptionRecord, &Context, FALSE); } else { /* Continue, go back to previous context */ Status = ZwContinue(&Context, FALSE); } } /* If we returned, raise a status */ RtlRaiseStatus(Status); }
VOID InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection ) /*++ Routine Description: A critical section object is initialized using Win32InitializeCriticalSection. Once a critical section object has been initialized threads within a single process may enter and exit critical sections using the critical section object. A critical section object may not me moved or copied. The application must also not modify the insides of the object, but must treat it as logically opaque. description-of-function. Arguments: lpCriticalSection - Supplies the address of a critical section object to be initialized. It is the callers resposibility to allocate the storage used by a critical section object. Return Value: None. --*/ { NTSTATUS Status; Status = RtlInitializeCriticalSection(lpCriticalSection); if ( !NT_SUCCESS(Status) ) { RtlRaiseStatus(Status); } }
/* * @implemented */ VOID NTAPI RtlRaiseStatus(IN NTSTATUS Status) { EXCEPTION_RECORD ExceptionRecord; CONTEXT Context; /* Capture the context */ RtlCaptureContext(&Context); /* Create an exception record */ ExceptionRecord.ExceptionAddress = _ReturnAddress(); ExceptionRecord.ExceptionCode = Status; ExceptionRecord.ExceptionRecord = NULL; ExceptionRecord.NumberParameters = 0; ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; /* Write the context flag */ Context.ContextFlags = CONTEXT_FULL; /* Check if user mode debugger is active */ if (RtlpCheckForActiveDebugger()) { /* Raise an exception immediately */ ZwRaiseException(&ExceptionRecord, &Context, TRUE); } else { /* Dispatch the exception */ RtlDispatchException(&ExceptionRecord, &Context); /* Raise exception if we got here */ Status = ZwRaiseException(&ExceptionRecord, &Context, FALSE); } /* If we returned, raise a status */ RtlRaiseStatus(Status); }
/* This could be implemented much more intelligently by mapping instances of a CoW zero page into the affected regions. We just RtlZeroMemory for now. */ BOOLEAN NTAPI CcZeroData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait) { PNOCC_BCB Bcb = NULL; PLIST_ENTRY ListEntry = NULL; LARGE_INTEGER LowerBound = *StartOffset; LARGE_INTEGER UpperBound = *EndOffset; LARGE_INTEGER Target, End; PVOID PinnedBcb, PinnedBuffer; PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap; DPRINT("S %08x%08x E %08x%08x\n", StartOffset->u.HighPart, StartOffset->u.LowPart, EndOffset->u.HighPart, EndOffset->u.LowPart); if (!Map) { NTSTATUS Status; IO_STATUS_BLOCK IOSB; PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE); ULONG ToWrite; if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE); RtlZeroMemory(ZeroBuf, PAGE_SIZE); Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart); End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart); // Handle leading page if (LowerBound.QuadPart != Target.QuadPart) { ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart, (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1)); DPRINT("Zero last half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite); Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB); if (!NT_SUCCESS(Status)) { ExFreePool(ZeroBuf); RtlRaiseStatus(Status); } DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite); RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite); Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE, UpperBound.QuadPart-Target.QuadPart), &IOSB); if (!NT_SUCCESS(Status)) { ExFreePool(ZeroBuf); RtlRaiseStatus(Status); } Target.QuadPart += PAGE_SIZE; } DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE); RtlZeroMemory(ZeroBuf, PAGE_SIZE); while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE) { DPRINT("Zero full page %08x%08x\n", Target.u.HighPart, Target.u.LowPart); Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, PAGE_SIZE, &IOSB); if (!NT_SUCCESS(Status)) { ExFreePool(ZeroBuf); RtlRaiseStatus(Status); } Target.QuadPart += PAGE_SIZE; } if (UpperBound.QuadPart > Target.QuadPart) { ToWrite = UpperBound.QuadPart - Target.QuadPart; DPRINT("Zero first half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite); Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB); if (!NT_SUCCESS(Status)) { ExFreePool(ZeroBuf); RtlRaiseStatus(Status); } DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite); RtlZeroMemory(ZeroBuf, ToWrite); Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE, UpperBound.QuadPart-Target.QuadPart), &IOSB); if (!NT_SUCCESS(Status)) { ExFreePool(ZeroBuf); RtlRaiseStatus(Status); } Target.QuadPart += PAGE_SIZE; } ExFreePool(ZeroBuf); return TRUE; } CcpLock(); ListEntry = Map->AssociatedBcb.Flink; while (ListEntry != &Map->AssociatedBcb) { Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList); CcpReferenceCache(Bcb - CcCacheSections); if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart && Bcb->FileOffset.QuadPart < UpperBound.QuadPart) { DPRINT("Bcb #%x (@%08x%08x)\n", Bcb - CcCacheSections, Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart); Target.QuadPart = MAX(Bcb->FileOffset.QuadPart, LowerBound.QuadPart); End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart, UpperBound.QuadPart); End.QuadPart = MIN(End.QuadPart, Bcb->FileOffset.QuadPart + Bcb->Length); CcpUnlock(); if (!CcPreparePinWrite(FileObject, &Target, End.QuadPart - Target.QuadPart, TRUE, Wait, &PinnedBcb, &PinnedBuffer)) { return FALSE; } ASSERT(PinnedBcb == Bcb); CcpLock(); ListEntry = ListEntry->Flink; /* Return from pin state */ CcpUnpinData(PinnedBcb, TRUE); } CcpUnpinData(Bcb, TRUE); } CcpUnlock(); return TRUE; }
/*********************************************************************** * InitializeCriticalSectionAndSpinCount (KERNEL32.@) */ BOOL WINAPI InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION *crit, DWORD spincount ) { NTSTATUS ret = RtlInitializeCriticalSectionAndSpinCount( crit, spincount ); if (ret) RtlRaiseStatus( ret ); return !ret; }
/*********************************************************************** * InitializeCriticalSection (KERNEL32.@) */ void WINAPI InitializeCriticalSection( CRITICAL_SECTION *crit ) { NTSTATUS ret = RtlInitializeCriticalSection( crit ); if (ret) RtlRaiseStatus( ret ); }
VOID loadimagedir ( IN PUCHAR filename, IN ULONG dirno, OUT PIMAGE_SECTION_HEADER SectionHeader ) { HANDLE filehandle; ULONG i, j, Dir; NTSTATUS status; IMAGE_DOS_HEADER DosImageHeader; IMAGE_NT_HEADERS NtImageHeader; PIMAGE_SECTION_HEADER pSectionHeader; status = openfile (&filehandle, "\\SystemRoot\\", filename); if (!NT_SUCCESS(status)) { status = openfile (&filehandle, "\\SystemRoot\\System32\\", filename); } if (!NT_SUCCESS(status)) { status = openfile (&filehandle, "\\SystemRoot\\System32\\Drivers\\", filename); } if (!NT_SUCCESS(status)) { RtlRaiseStatus (1); } try { readfile ( filehandle, 0, sizeof (DosImageHeader), (PVOID) &DosImageHeader ); if (DosImageHeader.e_magic != IMAGE_DOS_SIGNATURE) { RtlRaiseStatus (1); } readfile ( filehandle, DosImageHeader.e_lfanew, sizeof (NtImageHeader), (PVOID) &NtImageHeader ); if (NtImageHeader.Signature != IMAGE_NT_SIGNATURE) { RtlRaiseStatus (1); } // // read in complete sections headers from image // i = NtImageHeader.FileHeader.NumberOfSections * sizeof (IMAGE_SECTION_HEADER); j = ((ULONG) IMAGE_FIRST_SECTION (&NtImageHeader)) - ((ULONG) &NtImageHeader) + DosImageHeader.e_lfanew; if (i > BufferSize) { RtlRaiseStatus (1); } readfile ( filehandle, j, // file offset i, // length Buffer ); // // Find section with import directory // Dir = NtImageHeader.OptionalHeader.DataDirectory[dirno].VirtualAddress; i = 0; pSectionHeader = (PIMAGE_SECTION_HEADER)Buffer; for (; ;) { if (i >= NtImageHeader.FileHeader.NumberOfSections) { RtlRaiseStatus (1); } if (pSectionHeader->VirtualAddress <= Dir && pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData > Dir) { break; } i += 1; pSectionHeader += 1; } Dir -= pSectionHeader->VirtualAddress; pSectionHeader->VirtualAddress += Dir; pSectionHeader->PointerToRawData += Dir; pSectionHeader->SizeOfRawData -= Dir; *SectionHeader = *pSectionHeader; // // read in complete export section from image // if (SectionHeader->SizeOfRawData > BufferSize) { RtlRaiseStatus (1); } readfile ( filehandle, SectionHeader->PointerToRawData, SectionHeader->SizeOfRawData, Buffer ); } finally { // // Clean up // NtClose (filehandle); } }