예제 #1
0
SysStatus
PageAllocatorDefault::init(uval start, uval size)
{

    lock.init();
    lock.acquire();
    anchor = 0;
    freeList = 0;
    tassert((PAGE_ROUND_UP(start)==start),
	    err_printf("page allocator does not support unaligned memory\n"));
#ifdef DEBUG_MEMORY
    uval leakSize;
    leakSize = LeakProof::sizePerEntry*(size/PAGE_SIZE);
    if (KernelInfo::OnSim()) {
	leakSize = 200*LeakProof::sizePerEntry;
    } else {
	leakSize = 20000*LeakProof::sizePerEntry;
    }
    leakSize = size>(16*leakSize)?leakSize:size/16;
    leakSize = PAGE_ROUND_UP(leakSize);
    leakProof.init(start+size-leakSize,leakSize);
    size-=leakSize;
#endif /* #ifdef DEBUG_MEMORY */
    available = size;
    extendFreeList(start,size);
    anchor = freeList;
    freeList = freeList->low;
    anchor->start = start;
    anchor->size = size;
    anchor->low = anchor->high = 0;
    lock.release();
    return 0;
}
예제 #2
0
static
PVOID
AllocateGuarded(
    _In_ SIZE_T SizeRequested)
{
    NTSTATUS Status;
    SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE);
    PVOID VirtualMemory = NULL;
    PCHAR StartOfBuffer;

    Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS);

    if (!NT_SUCCESS(Status))
        return NULL;

    Size -= PAGE_SIZE;
    if (Size)
    {
        Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
        if (!NT_SUCCESS(Status))
        {
            Size = 0;
            Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
            ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
            return NULL;
        }
    }

    StartOfBuffer = VirtualMemory;
    StartOfBuffer += Size - SizeRequested;

    return StartOfBuffer;
}
예제 #3
0
파일: mkboot.c 프로젝트: jimix/k42
/* fix the program header that represetns the text segment.
 * make it large enough to contain the extra bits we are going
 * to put in - fix both the memory and file size
 */
int
adj_phdr(Elf32_Ehdr *eh32)
{
    Elf32_Phdr *phdr;
    int phdr_num;
    int i;
    int new_text_size;
    int text_mem_size;

    phdr = (Elf32_Phdr *)(kern_file+eh32->e_phoff);
    phdr_num = eh32->e_phnum;

    if (debug_level == 2) {
        printf("Dumping phdr information\n");
    }
    /* look for text segment and data segment info */
    for (i=0; i<phdr_num; i++,phdr++) {
        if (debug_level == 2) {
	    dump_phdr(phdr);
	}
        if (phdr->p_vaddr == TEXT_VADDR) {
	  text_file_size = phdr->p_filesz;
	  text_mem_size = phdr->p_memsz;
	  text_file_offset = phdr->p_offset;
	}
        if (phdr->p_vaddr == DATA_VADDR) {
	  old_data_file_offset = phdr->p_offset;
	}
    }

    if (old_data_file_offset < text_file_offset) {
      fprintf(stderr, "error data segment before text segment\n");
      exit(-1);
    }

    /* now go through and adjust text sizes and data offset */
    phdr = (Elf32_Phdr *)(kern_file+eh32->e_phoff);
    for (i=0; i<phdr_num; i++,phdr++) {
        if (phdr->p_vaddr == TEXT_VADDR) {
	    new_text_size = PAGE_ROUND_UP((BITS_VADDR - TEXT_VADDR) + bits_info.st_size);
	    phdr->p_filesz = new_text_size;
	    phdr->p_memsz = new_text_size;
	}
        if (phdr->p_vaddr == DATA_VADDR) {
	  data_file_offset = text_file_offset + new_text_size;
	  amount_push_back = data_file_offset - old_data_file_offset;
	  phdr->p_offset = data_file_offset;
	}
    }

    if (debug_level == 2) {
        printf("\n\n");
    }
    return 0;
}
예제 #4
0
파일: MPMsgMgr.C 프로젝트: BillTheBest/k42
void
MPMsgMgr::init(DispatcherID dspid, MemoryMgrPrimitive *pa,
	       MPMsgMgrRegistryRef &registry)
{
    SysStatus rc;

    sendQueue.init();
    replyQueue.init();

    allocMsgLock.init();
    thisDspID = dspid;

    // allocate array of buffers
    tassert((sizeof(MsgHolder) == MSG_HOLDER_SIZE), err_printf("oops\n"));
    const uval amt = NUM_MSGS * sizeof(MsgHolder);
    uval space;
    if (pa != NULL) {
	pa->alloc(space, amt, MSG_CHUNK_SIZE);
    } else {
	space = uval(allocGlobalPadded(amt));
    }
    tassert(space != 0, err_printf("couldn't allocate msg buffers\n"));
    msgHolder = (MsgHolder *) space;

    uval i;
    for (i = 0; i < NUM_MSGS; i++) {
	msgHolder[i].manager = this;
	msgHolder[i].busy = 0;
    }
    nextMsgIdx = 0;

    // Create the registry, but don't register ourselves yet because our
    // interrupt handlers haven't been installed.
    if (dspid == SysTypes::DSPID(0,0)) {
	if (registry!=NULL) {
	    uval* y = (uval*)PAGE_ROUND_UP((uval)&registry);
	    uval* x = (uval*)PAGE_ROUND_DOWN((uval)&registry);
	    while (x < y) {
		if (*x) {
		    err_printf("%p: %lx\n",x,*x);
		}
		++x;
	    }
	}

	passertMsg(registry == NULL,"MPMsgMgr already initialized %p\n",
		   registry);
	rc = MPMsgMgrRegistry::Create(registry, pa);
	tassert(_SUCCESS(rc), err_printf("MPMsgMgrRegistry::Create failed\n"));
    }
    registryRef = registry;
}
예제 #5
0
파일: send.c 프로젝트: GYGit/reactos
static
PVOID
AllocateReadOnly(
    _In_ SIZE_T SizeRequested)
{
    NTSTATUS Status;
    SIZE_T Size = PAGE_ROUND_UP(SizeRequested);
    PVOID VirtualMemory = NULL;

    Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READONLY);
    if (!NT_SUCCESS(Status))
        return NULL;

    return VirtualMemory;
}
예제 #6
0
파일: util.c 프로젝트: jcande/xenocryst
void *
allocate_memory(
    void
    )
{
    uint8_t *p;

    p = mmap(
            NULL,
            MEMORY_SIZE,
            PROT_READ|PROT_WRITE,
            MAP_ANONYMOUS|MAP_PRIVATE,
            -1,
            0
        );
    if (p == MAP_FAILED)
    {
        err(1, "mmap setup 0");
    }
    physical_memory = p;

    g_bf = get_aligned(physical_memory, MEMORY_SIZE, STRICTEST_ALIGNMENT, sizeof(*g_bf));
    if (g_bf == NULL)
    {
        errx(1, "alignment");
    }

    p = mmap(
            NULL,
            PAGE_ROUND_UP(sizeof(*sys_io_base)),
            PROT_READ|PROT_WRITE,
            MAP_ANONYMOUS|MAP_PRIVATE,
            -1,
            0
        );
    if (p == MAP_FAILED)
    {
        err(1, "mmap setup 1");
    }
    sys_io_base     = (SYS_IO_MEMORY_BASE *)p;
    syscall_memory  = &sys_io_base->syscall_memory;
    io_memory       = &sys_io_base->io_memory;

    memset(syscall_memory, 0, sizeof(*syscall_memory));
    memset(io_memory, 0, sizeof(*io_memory));

    return (void *)g_bf;
}
static
VOID
MakeReadOnly(
    PVOID Pointer,
    SIZE_T SizeRequested)
{
    NTSTATUS Status;
    SIZE_T Size = PAGE_ROUND_UP(SizeRequested);
    PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer);

    if (Size)
    {
        Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
        if (!NT_SUCCESS(Status))
        {
            Size = 0;
            Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
            ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
        }
    }
}
예제 #8
0
파일: util.c 프로젝트: jcande/xenocryst
void
cleanup_memory(
    void
    )
{
    uint32_t status;

    status = munmap(sys_io_base, PAGE_ROUND_UP(sizeof(*sys_io_base)));
    if (status != 0)
    {
        err(1, "munmap cleanup 0");
    }
    io_memory = NULL;

    status = munmap(physical_memory, MEMORY_SIZE);
    if (status != 0)
    {
        err(1, "munmap cleanup 1");
    }
    physical_memory = NULL;
}
예제 #9
0
/*virtual*/ SysStatus
ProcessShared<ALLOC>::getMemory(__in uval size, __inout uval &vaddr)
{
    // LOCKING: none needed, only internal access is getRef,
    // comes back and allocates region via region list
    SysStatus rc;
    FCMRef fcmRef;
    RegionRef regionRef;

    size = PAGE_ROUND_UP(size);

//    cprintf("in process default alloc region %ld\n", size);

    // create region on the users behalf with the size and memory type desired
    rc = FCMPrimitive<PageSet<AllocGlobal>,AllocGlobal>::Create(fcmRef);
    if (rc) return rc;

    rc = RegionDefault::CreateFixedLen(regionRef, getRef(),
				       vaddr, size, 0, fcmRef, 0,
				       AccessMode::writeUserWriteSup);
    return rc;
}
예제 #10
0
/* unlocked version exists to allow one to atomically expand space while
 * trying to allocate memory, so only one thread expands the space if
 * all try to allocate at the same time
 */
SysStatus
PageAllocatorDefault::locked_deallocPages(uval vaddr, uval size)
{
    _ASSERT_HELD(lock);			// must be called with lock held
#ifdef marcdebug
    marcCheckAvail();
#endif /* #ifdef marcdebug */

    size = PAGE_ROUND_UP(size);
    tassertMsg((vaddr & PAGE_MASK) == 0, "%lx not page aligned?\n",vaddr);

#ifdef DEBUG_MEMORY
    leakProof.free(vaddr,size);
#if 0 /*DEBUG_MEMORY too slow on simulator*/
    {
	uval* p=(uval*)vaddr;
	//can't aford to clear monster allocations here
	for (;p<(uval*)(vaddr+PAGE_SIZE);*(p++)=(uval)0xDFDFDFDFDFDFDFDFLL);
    }
#endif /* #if 0 */
#endif /* #ifdef DEBUG_MEMORY */
#ifdef marcdebug
    marcaddr=vaddr;marcsize=size;
    if ((vaddr == marcstop) || (vaddr & (PAGE_SIZE-1))) breakpoint();
#endif /* #ifdef marcdebug */

    sanity(vaddr, size);

    // first check for coallesce
    tassert(((vaddr & (~PAGE_MASK)) == vaddr), err_printf("not aligned?\n"));

    available += size;
    freePages *cur = anchor;
    freePages **top= 0;
    freePages *cur1;
    freePages **top1;
    uval topSize = 0;			// size of node top is in
    // look for coalesce
    while (cur) {
	if (cur->start+cur->size == vaddr) {
	    cur->size += size;
	    // No find smallest bigger than this
	    if ((cur1=cur->high)) {
		top1 = &(cur->high);
		while (cur1->low) {
		    top1 = &(cur1->low);
		    cur1 = cur1->low;
		}
		if ((cur->start+cur->size) == cur1->start) {
		    //coalesce this as well
		    cur->size += cur1->size;
		    *top1 = cur1->high;
		    cur1->low = freeList;
		    freeList = cur1;
		}
	    }
	    goto enlarge;
	} else if (vaddr+size == cur->start) {
	    // similar searching to the left
	    cur->start = vaddr;
	    cur->size += size;
	    if ((cur1 = cur->low)) {
		top1 = &(cur->low);
		while (cur1->high) {
		    top1= &(cur1->high);
		    cur1 = cur1->high;
		}
		if ((cur1->start+cur1->size)==cur->start) {
		    //coalesce this as well
		    cur->start = cur1->start;
		    cur->size += cur1->size;
		    *top1 = cur1->low;
		    cur1->low = freeList;
		    freeList = cur1;
		}
	    }
	    goto enlarge;
	} else {
	    topSize = cur->size;
	    if (vaddr<cur->start) {
		top = &(cur->low);
		cur = cur->low;
	    } else {
		top = &(cur->high);
		cur = cur->high;
	    }
	}
    }

    // no coalesce found - so make new free block
    cur = freeList;			// freelist never empty
    if (!(freeList = freeList->low)) {
	// may modify vaddr and size if
	// space for freelist can't be found elsewhere
	extendFreeList(vaddr,size);
	if (size == 0) goto done;
    }
    // back to the main story - cur is the new node
    cur->start = vaddr;
    cur->size = size;
    anchor = add(anchor,cur);
done:
    sanity();
#ifdef marcdebug
    marcCheckAvail();
#endif /* #ifdef marcdebug */
    return 0;

enlarge:
    // cur points to enlarged block, topSize size of parent,
    // top points to parent
    if (top && (cur->size > topSize)) {
	// cur has gotten be enough to be in wrong place
	// remove it from current place
	*top = merge(cur->low,cur->high);
	// reinsert it
	anchor = add(anchor,cur);
    }
    goto done;
}
예제 #11
0
/*
 *
 * Allocate a region with an alignment or fail.
 * The aligment is specifed as an alignment and an offset.
 * The resultant vaddr will satisfy vaddr mod align = offset.
 * The old style power of two interface is gotten with a power of two
 * align value, and a zero offset value.
 * This routine does a brute force search and is relatively expensive.
 * Note the bounded stack size - this may cause the allocation to fail
 * when it could be done, or cause a larger than necessary block to be
 * fragmented.
 */
SysStatus
PageAllocatorDefault::allocPagesAligned(uval &vaddr, uval size,
					uval align, uval offset,
					uval f, VPNum n)
{
    (void)f; (void)n;			// flags and node parms not used here

    size = PAGE_ROUND_UP(size);

    lock.acquire();
#ifdef marcdebug
    marcCheckAvail();
#endif /* #ifdef marcdebug */

 retry:

#define STACK_SIZE 64			// Made up value - should be OK
    freePages *stack[STACK_SIZE];
    uval sp = 0;
    freePages* cur = anchor;
    freePages** top = &anchor;
    freePages *found = 0;
    freePages **foundtop = 0;

    //search for first (smallest address) block which satisfies aligned request

    if (!cur) goto bad;

    while (1) {
	/* this test sees if the aligned request is within this block
	 * start by rounding block address up as required
	 * vaddr will always be ge cur->start
	 */
	vaddr = ((cur->start+align-offset-1)/align)*align+offset;
	if ((vaddr+size) <= (cur->start+cur->size)) {
	    found = cur;
	    foundtop = top;
	}
	// if block is completely too small or has no successors backtrack
	if ((cur->size < size) || (!(cur->low) && !(cur->high))) {
	    if (found) break;
	    if (sp) {
		cur = stack[--sp];
		top = &(cur->high);
		cur = cur->high;	// every stack entry has a high subtree
	    } else {
		goto bad;
	    }
	} else if (cur->low) {		// continue down the tree searching
	    if (cur->high && sp<STACK_SIZE) stack[sp++] = cur;
	    top = &(cur->low);
	    cur = cur->low;
	} else {
	    top = &(cur->high);
	    cur = cur->high;
	}
    }
    // we reach here with found pointing to first feasible block, foundtop
    // to anchor for that block in the tree
    // first remove that block
    vaddr = ((found->start+align-offset-1)/align)*align+offset;
    allocFromBlock(found,foundtop,vaddr,size);
    available -= size;
    tassertMsg((vaddr & PAGE_MASK) == 0, "%lx not page aligned?\n",vaddr);
    sanity(vaddr, size);
#ifdef marcdebug
    marcCheckAvail();
#endif /* #ifdef marcdebug */
#ifdef DEBUG_MEMORY
    {
	leakProof.alloc(vaddr,size);
#if 0
	uval* p=(uval*)vaddr;
	//don't kill pages for now - simulator too slow
	//most unitialized bugs caught by clobber in alloc.H
	for (;p<(uval*)(vaddr+PAGE_SIZE);*(p++)=(uval)0xBFBFBFBFBFBFBFBFLL);
#endif /* #if 0 */
    }
#endif /* #ifdef DEBUG_MEMORY */
    lock.release();
    return 0;

 bad:
    // call virtual function possibly overridden by subclass to get more space
    if (_SUCCESS(getMoreMem(size))) goto retry;

    lock.release();

    tassertWrn(0, "warning allocator out of space: "
	       "size %lx align %lx offset %lx\n", size, align, offset);
    vaddr = 0;
    return _SERROR(1476, 0, ENOMEM);
}
예제 #12
0
/*
 *
 *Allocate the first region of size or return null
 */
SysStatus
PageAllocatorDefault::allocPages(uval &vaddr, uval size, uval f, VPNum n)
{
    (void)f; (void)n;			// flags and node parms not used here

    freePages **top;			// address of pointer to subtree
    freePages *cur, *next;

    // round up to a multiple of a page
    size = PAGE_ROUND_UP(size);

    lock.acquire();

#ifdef marcdebug
    marcCheckAvail();
#endif /* #ifdef marcdebug */

 retry:

    top = &anchor;
    cur = anchor;
    // top node is (one of) the largest blocks
    if (!cur || cur->size < size) goto nospace;
    // search for lowest address block which is big enough
    while (1) {
	if ((next = cur->low) && (next->size == cur->size)) {
	    //To avoid quadradic behavior allocating a number of
	    //blocks of the same size, we reroot the subtree at the
	    //lower address node of the same size
	    *top = next;
	    cur->low = next->high;
	    next->high = cur;
	} else if (next && (next->size >= size)) {
	    top = &(cur->low);
	} else if ((next=cur->high) && (next->size >= size)) {
	    top = &(cur->high);
	} else break;
	cur = next;
    }
    // cur now points to the lowest address node which can provide size
    // top points to the pointer to cur in the tree

    vaddr = cur->start;
    tassert(((vaddr & (~PAGE_MASK)) == vaddr), err_printf("not aligned?\n"));
    cur->start += size;
    cur->size -= size;
    next = merge(cur->low,cur->high);

    if (cur->size) {
	next = add(next,cur);
    } else {
	cur->low = freeList;
	freeList = cur;
    }
    *top = next;
    available -= size;
    sanity(vaddr,size);
#ifdef DEBUG_MEMORY
    {
	leakProof.alloc(vaddr,size);
#if 0
	uval* p=(uval*)vaddr;
	//don't kill pages for now - simulator too slow
	//most unitialized bugs caught by clobber in alloc.H
	for (;p<(uval*)(vaddr+PAGE_SIZE);*(p++)=(uval)0xBFBFBFBFBFBFBFBFLL);
#endif /* #if 0 */
    }
#endif /* #ifdef DEBUG_MEMORY */
#ifdef marcdebug
    marcCheckAvail();
#endif /* #ifdef marcdebug */
    lock.release();
    return 0;

 nospace:
    // call virtual function possibly overridden by subclass to get more space
    if (_SUCCESS(getMoreMem(size))) goto retry;

    tassertWrn(0, "warning allocator out of space: size %lx\n", size);

    lock.release();

    return _SERROR(1474, 0, ENOMEM);
}
예제 #13
0
/*

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;
}
예제 #14
0
NTSTATUS openProcByName(PHANDLE pProcess, PUNICODE_STRING pProcName, BOOLEAN useDebugPrivilege) {
	SYSTEM_PROCESS_INFORMATION procInfo;
	OBJECT_ATTRIBUTES procAttr;
	OBJECT_BASIC_INFORMATION processHandleInfo;
	CLIENT_ID cid;
	BOOLEAN oldValue;
	HANDLE pid;

	NTSTATUS status = STATUS_CACHE_PAGE_LOCKED;
	ULONG procListSize = 0;
	ULONGLONG memSize = 0;
	ULONG obQueryLen = 0;
	PVOID pProcListHead = NULL;
	PSYSTEM_PROCESS_INFORMATION pProcEntry = NULL;

	do {
		if (!pProcName || !pProcess) {
			status = STATUS_INVALID_PARAMETER;
			break;
		}
		
		*pProcess = NULL;

		///Since we specify a buffer size of 0 the buffer must overflow for sure even if there was running a
		///single process only. If we don't receive the dedicated error, something other has gone wrong
		///and we cannot rely on the return length.
		status = NtQuerySystemInformation(SystemProcessInformation, &procInfo, procListSize, &procListSize);
		if (STATUS_INFO_LENGTH_MISMATCH != status)
			break;

		memSize = PAGE_ROUND_UP(procListSize) + PAGE_SIZE; ///We better allocate one page extra
														   ///since between our "test" call and the real call below
														   ///additional processes might be started. (race condition)
		status = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &pProcListHead, 0, &memSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
		if (status) {
			pProcListHead = NULL;
			break;
		}

		///By now, we have allocated a buffer large enough for the complete process list,
		///even if some new processes have been started in the mean time.
		///Hence, the next call is entirely expected to succeed.
		procListSize = (ULONG)memSize;
		status = NtQuerySystemInformation(SystemProcessInformation, pProcListHead, procListSize, &procListSize);
		if (status)
			break;

		pid = NULL;
		pProcEntry = pProcListHead;				///The list of all system processes is a so called singly linked list.
		while (pProcEntry->NextEntryOffset) {	///If NextEntryOffset member is NULL, we have reached the list end (tail).
			pProcEntry = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)pProcEntry + pProcEntry->NextEntryOffset);
			//DebugPrint2A("PID: %d, %wZ", pProcEntry->UniqueProcessId, pProcEntry->ImageName);
			if (0 == RtlCompareUnicodeString(pProcName, &pProcEntry->ImageName, TRUE)) {
				pid = pProcEntry->UniqueProcessId;
				break;
			}
		}

		if (!pid) {
			status = STATUS_OBJECT_NAME_NOT_FOUND;
			break;
		}
			
		if (useDebugPrivilege) {
			status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &oldValue);
			if (status){			///Since we're for some reason supposed to use the SeDebugPrivilege,
				useDebugPrivilege = FALSE;
				break;				///we fail deliberately if we can't enable it.
			}
		}

		InitializeObjectAttributes(&procAttr, NULL, 0, NULL, NULL);
		cid.UniqueThread = (HANDLE)0;
		cid.UniqueProcess = pid;

		///Opening a process for full access might be less suspicious than opening with our real intentions.
		status = NtOpenProcess(pProcess, PROCESS_ALL_ACCESS, &procAttr, &cid);
		if (status) {
			///Most likely STATUS_ACCESS_DENIED if
			///either we didn't specify the useDebugPrivilege flag when opening a cross session process
			///or if we tried to open an elevated process while running non-elevated
			///or if the process being opened is a so-called "Protected Process".

			///In x64 windows, HIPS or AV drivers have the possibility to legally
			///receive a notification if a process is about to open a handle to another process.
			///In those ObCallback routines they cannot completely deny the opening.
			///However, they are able to modify the access masks, so a handle supposed for VM operations still
			///will be lacking the PROCESS_VM_XXX rights, for example. If we therefore query the handle rights
			///we can still return an appropriate error if wasn't granted the rights we want
			///And are not going to fail at first when performing our process operations.
			*pProcess = NULL;
			break;
		}

		status = NtQueryObject(*pProcess, ObjectBasicInformation, &processHandleInfo, sizeof(OBJECT_BASIC_INFORMATION), &obQueryLen);
		if (status)	///Not sure if this call ever will fail...
			break;

		///Maybe, HIPS just wanted to deny PROCESS_TERMINATE/PROCESS_SUSPEND right?
		///If so, we don't care. We're only interested in VM rights.
		if (MIN_VM_ACCESS_MASK & ~processHandleInfo.GrantedAccess) {
			status = STATUS_UNSUCCESSFUL;
			break;
		}
	} while (status);

	if (status && pProcess) {
		if (*pProcess) {
			NtClose(*pProcess);
			*pProcess = NULL;
		}
	}

	if (pProcListHead) {
		memSize = 0;
		NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pProcListHead, &memSize, MEM_RELEASE); ///We don't need the list anymore.
	}
		
	if (useDebugPrivilege)
		RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, oldValue, FALSE, &oldValue);		///We don't need the privilege anymore.

	return status;
}
예제 #15
0
VOID
NTAPI
MiInitializeSpecialPool()
{
    ULONG SpecialPoolPtes, i;
    PMMPTE PointerPte;

    /* Check if there is a special pool tag */
    if ((MmSpecialPoolTag == 0) ||
        (MmSpecialPoolTag == -1)) return;

    /* Calculate number of system PTEs for the special pool */
    if ( MmNumberOfSystemPtes >= 0x3000 )
        SpecialPoolPtes = MmNumberOfSystemPtes / 3;
    else
        SpecialPoolPtes = MmNumberOfSystemPtes / 6;

    /* Don't let the number go too high */
    if (SpecialPoolPtes > 0x6000) SpecialPoolPtes = 0x6000;

    /* Round up to the page size */
    SpecialPoolPtes = PAGE_ROUND_UP(SpecialPoolPtes);

    ASSERT((SpecialPoolPtes & (PTE_PER_PAGE - 1)) == 0);

    /* Reserve those PTEs */
    do
    {
        PointerPte = MiReserveAlignedSystemPtes(SpecialPoolPtes, 0, /*0x400000*/0); // FIXME:
        if (PointerPte) break;

        /* Reserving didn't work, so try to reduce the requested size */
        ASSERT(SpecialPoolPtes >= PTE_PER_PAGE);
        SpecialPoolPtes -= 1024;
    } while (SpecialPoolPtes);

    /* Fail if we couldn't reserve them at all */
    if (!SpecialPoolPtes) return;

    /* Make sure we got enough */
    ASSERT(SpecialPoolPtes >= PTE_PER_PAGE);

    /* Save first PTE and its address */
    MiSpecialPoolFirstPte = PointerPte;
    MmSpecialPoolStart = MiPteToAddress(PointerPte);

    for (i = 0; i<512; i++)
    {
        /* Point it to the next entry */
        PointerPte->u.List.NextEntry = &PointerPte[2] - MmSystemPteBase;

        /* Move to the next pair */
        PointerPte += 2;
    }

    /* Save extra values */
    MiSpecialPoolExtra = PointerPte;
    MiSpecialPoolExtraCount = SpecialPoolPtes - 1024;

    /* Mark the previous PTE as the last one */
    MiSpecialPoolLastPte = PointerPte - 2;
    MiSpecialPoolLastPte->u.List.NextEntry = MM_EMPTY_PTE_LIST;

    /* Save end address of the special pool */
    MmSpecialPoolEnd = MiPteToAddress(MiSpecialPoolLastPte + 1);

    /* Calculate maximum non-paged part of the special pool */
    MiSpecialPagesNonPagedMaximum = MmResidentAvailablePages >> 4;

    /* And limit it if it turned out to be too big */
    if (MmNumberOfPhysicalPages > 0x3FFF)
        MiSpecialPagesNonPagedMaximum = MmResidentAvailablePages >> 3;

    DPRINT1("Special pool start %p - end %p\n", MmSpecialPoolStart, MmSpecialPoolEnd);

    //MiTestSpecialPool();
}
예제 #16
0
NTSTATUS
SetupCopyFile(
    PWCHAR SourceFileName,
    PWCHAR DestinationFileName)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE FileHandleSource;
    HANDLE FileHandleDest;
    static IO_STATUS_BLOCK IoStatusBlock;
    FILE_STANDARD_INFORMATION FileStandard;
    FILE_BASIC_INFORMATION FileBasic;
    ULONG RegionSize;
    UNICODE_STRING FileName;
    NTSTATUS Status;
    PVOID SourceFileMap = 0;
    HANDLE SourceFileSection;
    SIZE_T SourceSectionSize = 0;
    LARGE_INTEGER ByteOffset;

#ifdef __REACTOS__
    RtlInitUnicodeString(&FileName,
                         SourceFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtOpenFile(&FileHandleSource,
                        GENERIC_READ,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ,
                        FILE_SEQUENTIAL_ONLY);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName);
        goto done;
    }
#else
    FileHandleSource = CreateFileW(SourceFileName,
                                   GENERIC_READ,
                                   FILE_SHARE_READ,
                                   NULL,
                                   OPEN_EXISTING,
                                   0,
                                   NULL);
    if (FileHandleSource == INVALID_HANDLE_VALUE)
    {
        Status = STATUS_UNSUCCESSFUL;
        goto done;
    }
#endif

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,
                                    &FileStandard,
                                    sizeof(FILE_STANDARD_INFORMATION),
                                    FileStandardInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,&FileBasic,
                                    sizeof(FILE_BASIC_INFORMATION),
                                    FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtCreateSection(&SourceFileSection,
                             SECTION_MAP_READ,
                             NULL,
                             NULL,
                             PAGE_READONLY,
                             SEC_COMMIT,
                             FileHandleSource);
    if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName);
      goto closesrc;
    }

    Status = NtMapViewOfSection(SourceFileSection,
                                NtCurrentProcess(),
                                &SourceFileMap,
                                0,
                                0,
                                NULL,
                                &SourceSectionSize,
                                ViewUnmap,
                                0,
                                PAGE_READONLY );
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName);
        goto closesrcsec;
    }

    RtlInitUnicodeString(&FileName,
                         DestinationFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtCreateFile(&FileHandleDest,
                          GENERIC_WRITE | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          0,
                          FILE_OVERWRITE_IF,
                          FILE_NO_INTERMEDIATE_BUFFERING |
                          FILE_SEQUENTIAL_ONLY |
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0);
    if (!NT_SUCCESS(Status))
    {
        /* Open may have failed because the file to overwrite
         * is in readonly mode
         */
        if (Status == STATUS_ACCESS_DENIED)
        {
            FILE_BASIC_INFORMATION FileBasicInfo;

            /* Reattempt to open it with limited access */
            Status = NtCreateFile(&FileHandleDest,
                                  FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
                                  &ObjectAttributes,
                                  &IoStatusBlock,
                                  NULL,
                                  FILE_ATTRIBUTE_NORMAL,
                                  0,
                                  FILE_OPEN,
                                  FILE_NO_INTERMEDIATE_BUFFERING |
                                  FILE_SEQUENTIAL_ONLY |
                                  FILE_SYNCHRONOUS_IO_NONALERT,
                                  NULL,
                                  0);
            /* Fail for real if we cannot open it that way */
            if (!NT_SUCCESS(Status))
            {
                DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
                goto unmapsrcsec;
            }

            /* Zero our basic info, just to set attributes */
            RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
            /* Reset attributes to normal, no read-only */
            FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
            /* We basically don't care about whether it succeed:
             * if it didn't, later open will fail
             */
            NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasicInfo,
                                 sizeof(FileBasicInfo), FileBasicInformation);

            /* Close file */
            NtClose(FileHandleDest);

            /* And re-attempt overwrite */
            Status = NtCreateFile(&FileHandleDest,
                                  GENERIC_WRITE | SYNCHRONIZE,
                                  &ObjectAttributes,
                                  &IoStatusBlock,
                                  NULL,
                                  FILE_ATTRIBUTE_NORMAL,
                                  0,
                                  FILE_OVERWRITE_IF,
                                  FILE_NO_INTERMEDIATE_BUFFERING |
                                  FILE_SEQUENTIAL_ONLY |
                                  FILE_SYNCHRONOUS_IO_NONALERT,
                                  NULL,
                                  0);
        }

        /* We failed */
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
            goto unmapsrcsec;
        }
    }

    RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
    IoStatusBlock.Status = 0;
    ByteOffset.QuadPart = 0ULL;
    Status = NtWriteFile(FileHandleDest,
                         NULL,
                         NULL,
                         NULL,
                         &IoStatusBlock,
                         SourceFileMap,
                         RegionSize,
                         &ByteOffset,
                         NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize);
        goto closedest;
    }

    /* Copy file date/time from source file */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileBasic,
                                  sizeof(FILE_BASIC_INFORMATION),
                                  FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
        goto closedest;
    }

    /* shorten the file back to it's real size after completing the write */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileStandard.EndOfFile,
                                  sizeof(FILE_END_OF_FILE_INFORMATION),
                                  FileEndOfFileInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
    }

closedest:
    NtClose(FileHandleDest);

unmapsrcsec:
    NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap);

closesrcsec:
    NtClose(SourceFileSection);

closesrc:
    NtClose(FileHandleSource);

done:
    return Status;
}
예제 #17
0
NTSTATUS obtainImageFileEatEntries(PVOID pImageFileBase, PUCHAR pListBuffer, PULONGLONG pNeededBufferSize, PUCHAR pModuleName, ULONGLONG moduleNameSize){
	UCHAR szError[] = "Error";
	ULONGLONG nameLength = 0;
	ULONGLONG maxReadSize = 0;
	ULONGLONG minExportSize = 0;
	NTSTATUS status = STATUS_UNABLE_TO_UNLOAD_MEDIA;
	ULONGLONG exportSize = 0;
	PIMAGE_NT_HEADERS64 pImagePeHdr = NULL;
	PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
	PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
	PULONG piListBuffer = NULL;
	PULONG pNameRvaArray = NULL;
	PUCHAR pCurrName = NULL;
	PUCHAR pListPointer = NULL;

	if (!pImageFileBase || !pNeededBufferSize || !pModuleName)
		return STATUS_INVALID_PARAMETER;

	if (!pListBuffer && *pNeededBufferSize)
		return STATUS_INVALID_PARAMETER;

	pImagePeHdr = (PIMAGE_NT_HEADERS64)((PUCHAR)pImageFileBase + ((PIMAGE_DOS_HEADER)pImageFileBase)->e_lfanew);
	pDataDirectory = pImagePeHdr->OptionalHeader.DataDirectory;
	///Is it safe to read the data directory array until the desired entry?
	maxReadSize = sizeof(IMAGE_DATA_DIRECTORY) * (IMAGE_DIRECTORY_ENTRY_EXPORT + 1);
	status = validatePePointer(pImageFileBase, pDataDirectory, maxReadSize, TRUE);
	if (status)
		return status;

	pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)pImageFileBase + pDataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
	///Is it safe to read all members of the export directory structure?
	maxReadSize = sizeof(IMAGE_EXPORT_DIRECTORY);
	status = validatePePointer(pImageFileBase, pExportDirectory, maxReadSize, FALSE);
	if (status)
		return status;

	///Is the claimed export size viable?
	exportSize = pDataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
	status = validatePePointer(pImageFileBase, pExportDirectory, exportSize, FALSE);
	if (status)
		return status;

	///By doing some math one can prove that the maximum needed buffer size is guaranteed
	///to not exceed the export directory size: Due to PE specifications the export size is going to be
	///more than at least: all_namelengths + NumberOfNames * (sizeof(ANSI_NULL) + sizeof(ULONG)). 
	///This simplifies to: all_namelengths + 5 * NumberOfNames.
	///Since we will be adding one more char for each name entry, our actual needed buffer size becomes at maximum:
	///all_namelengths + NumberOfNames * 2 * sizeof(char), which simplifies to all_namelengths + 2 * NumberOfNames.
	///As we can see, there exists still a huge safety margin, even though we completely neglected
	///the sizes of both the function RVA and the ordinal tables. It is therefore fully sufficient if we
	///set the needed buffer size to the export size.
	if (*pNeededBufferSize < PAGE_ROUND_UP(exportSize)){
		*pNeededBufferSize = PAGE_ROUND_UP(exportSize);
		return STATUS_BUFFER_TOO_SMALL;
	}

	///Is it safe to scan down the name RVA array?
	pNameRvaArray = (PULONG)((PUCHAR)pImageFileBase + pExportDirectory->AddressOfNames);
	maxReadSize = pExportDirectory->NumberOfNames * sizeof(ULONG);
	status = validatePePointer(pImageFileBase, pNameRvaArray, maxReadSize, FALSE);
	if (status)
		return status;

	///Since NumberOfNames can be any value, we need to roughly estimate the exportSize
	///according to the combined sizes of the three export describing arrays.
	///If this yields to greater export size than the claimed export size, the image must be rejected.
	minExportSize = sizeof(ULONG) * pExportDirectory->NumberOfFunctions + pExportDirectory->NumberOfNames * sizeof(ULONG) + sizeof(USHORT) + sizeof(ANSI_NULL);
	if (exportSize <= minExportSize)
		return STATUS_INVALID_IMAGE_FORMAT;

	///It is NOT guaranteed, that an entry in the name RVA array at position 'n' has a value
	///which also orders as the n-th element in the entire name RVA range.
	///It is therefore not permissible to calculate the name length by simply doing
	///pNameRvaArray[n+1] - pNameRvaArray[n]. If we still want to make this assumption
	///the RVAs values must be sorted until they are in an ascending order.
	///By utilizing the last unused bytes of the caller-allocated buffer we avoid having
	///to allocate a buffer on our own. Doing the math above (see exportsize calculation)
	///one can prove that the safety margin is sufficient if we use the buffer in that way.
	piListBuffer = (PULONG)(pListBuffer + *pNeededBufferSize - pExportDirectory->NumberOfNames * sizeof(ULONG));
	RtlCopyMemory(piListBuffer, pNameRvaArray, pExportDirectory->NumberOfNames * sizeof(ULONG));
	qsort(piListBuffer, (ULONGLONG)pExportDirectory->NumberOfNames, sizeof(ULONG), mycompare);

	///Is it safe to read the module name?
	maxReadSize = pNameRvaArray[0] - pExportDirectory->Name;
	status = validatePePointer(pImageFileBase, (PVOID)((PUCHAR)pImageFileBase + pExportDirectory->Name), maxReadSize, FALSE);
	if (status)
		return status;

	if (moduleNameSize < maxReadSize)
		return STATUS_STACK_OVERFLOW;
	
	RtlCopyMemory(pModuleName, (PUCHAR)pImageFileBase + pExportDirectory->Name, maxReadSize);
	pModuleName[maxReadSize - 1] = 0x0;
	pListPointer = pListBuffer;
	printf_s("\nmodule name: %s", pModuleName);

	pNameRvaArray = piListBuffer;
	for (ULONG i = 0; i < pExportDirectory->NumberOfNames; i++){
		///Will none of the obtained name RVAs evaluate to an invalid name pointer?
		if (!(exportSize + pDataDirectory->VirtualAddress > pNameRvaArray[i]))
			return STATUS_INVALID_IMAGE_FORMAT;
		
		pCurrName = (PUCHAR)pImageFileBase + pNameRvaArray[i];
		///At the end of RVA array there is no longer a next name entry.
		///There must by PE design a terminating zero though, which we're going to exploit
		///in order to still have a valid name length.
		if (pExportDirectory->NumberOfNames - 1 == i){
			int j = 0;
			while (pCurrName[j])
				j++;

			nameLength = j;
		}
		else{
			nameLength = (ULONGLONG)(pNameRvaArray[i + 1] - pNameRvaArray[i]/*pNextName - pCurrName*/) - 1;
		}
		///If for some reason the allocated buffer is about to be overran
		///we print an error signature into the buffer and abort the scan.
		///In regard of our thousands of sanity checks this surely denotes a major PE damage.
		///Additionally, we break a little earlier to not have the failure overwrite the sorted RVAs.
		if ((PUCHAR)piListBuffer <= pListPointer + nameLength + sizeof(WCHAR)){
			pCurrName = szError;
			nameLength = sizeof(szError) - 1;
			pListPointer = (PUCHAR)piListBuffer - (nameLength + sizeof(WCHAR));
			///Indirect break, bail out.
			i = pExportDirectory->NumberOfNames;
		}
		
		RtlCopyMemory(pListPointer, pCurrName, nameLength);
		*(PWCHAR)&pListPointer[nameLength] = (WCHAR)0x0A0D;
		pListPointer += nameLength + sizeof(WCHAR);
	}
	
	///Hit two birds with one stone by replacing last 0D 0A sequence with a terminating WCHAR 0.
	*((PWCHAR)pListPointer - 1) = (WCHAR)0x0;

	*pNeededBufferSize = (ULONGLONG)(pListPointer - pListBuffer);
	return STATUS_SUCCESS;
}
예제 #18
0
/* virtual */ SysStatus
PacketRing::init(ProcessID caller, uval &vaddrTX, uval &vaddrRX, uval txSize, 
                 uval rxSize)
{
    SysStatus rc;
    uval size;

    refCount = 0;
    beingDestroyed = 0;
    pageArrayNumTX = 0;
    pageArrayNumRX = 0;
    packetCountRX = 0;

    ringCurrentIdxRX = 0;
    ringCurrentOffsetRX = 0;

    ringCurrentIdxTX = pageArrayNumRX;
    ringCurrentOffsetTX = 0;

    beginIdxRX = 0;
    beginOffsetRX = 0;

    beginIdxTX = pageArrayNumRX;
    beginOffsetTX = 0;

    packetsReceived = 0;
    packetsTransmitted = 0;
    packetsDropped = 0;
    packetsRecvCoalesced = 0;

    fcmOffset = 0;

    // Get references for the process
    DREFGOBJ(TheProcessSetRef)->getRefFromPID(caller, 
					      (BaseProcessRef &)processRef);

    // Create new FCM
    rc = FCMFixed<AllocGlobal>::Create(fcmRef);
    if (_FAILURE(rc)) {
	err_printf("create fcm failed: %#lx\n", rc);
	return rc;
    }

    size = PAGE_ROUND_UP(rxSize) + PAGE_ROUND_UP(txSize) + PAGE_SIZE;

    // Create shared region
    rc = RegionDefault::CreateFixedLen(regionRef, processRef, baseVaddr, size,
                                       0, fcmRef, 0, 
				       AccessMode::writeUserWriteSup);
    if (_FAILURE(rc)) {
        err_printf("create region failed: %#lx\n", rc);
        return rc;
    }
    
    // Allocate packet rings
    rc = allocRings(PAGE_ROUND_UP(txSize), PAGE_ROUND_UP(rxSize)); 
    if (_FAILURE(rc)) {
        err_printf("allocRings failed\n");
	return rc;
    }

    // Allocate ctrl region
    rc = allocCtrl();
    if (_FAILURE(rc)) {
        err_printf("allocCtrl failed\n");
        return rc;
    }

    vaddrRX = baseVaddr;
    vaddrTX = baseVaddr + PAGE_ROUND_UP(rxSize);
    
    return 0;
}
예제 #19
0
SysStatus
RegionReplicated::RegionReplicatedRoot::initRegion(
    ProcessRef pRef, uval &vaddr, uval vaddr2, uval size,
    uval alignreq, FRRef frRef, uval writable, uval fOff,
    AccessMode::mode accessreq, uval useVaddr, RegionType::Type regionType)
{
    SysStatus rc=0;
    PMRef pmRef;
    size = PAGE_ROUND_UP(size);

    tassertWrn(!useVaddr || (PAGE_ROUND_DOWN(vaddr)==vaddr),
	       "creating an unaligned region, vaddr=%lx\n", vaddr);

    rc = DREF(pRef)->getPM(pmRef);
    if (!_SUCCESS(rc)) return rc;

    regionState = CREATING;

    /*
     * we record the actual permission of the FR.  This is so that
     * if a debugger asks to write a readonly mapping, we can decide
     * if its legal.
     * Of course, we also use this to prevent an initial writable
     * mapping of a read only FR.
     */
    writeAllowed = writable;

    rc = DREF(pRef)->getHATProcess(hat);
    tassert(_SUCCESS(rc), err_printf("process destroyed\n"));
    regionVaddr   = vaddr;
    regionSize    = size;
    proc          = pRef;
    access        = accessreq;
    alignment     = alignreq;
    fileOffset    = fOff;

    /* can make regions without an fcm - see redzone for example
     * we attach first so we can ask fcm if it uses shared segments
     */
    if (frRef) {
	rc = DREF(frRef)->attachRegion(fcm, (RegionRef)getRef(), pmRef,
				       accessreq);
	tassertWrn(_SUCCESS(rc), "attach failed\n");
	if (_FAILURE(rc)) {
	    fcm = 0;			// clear our fcm field
	    tassert(0,err_printf("attach failed\n"));
	    // FIXME we going to have a problem if we just call destroy
	    //       because that will attempt to create a
	    //       rep to call the method on, but we are currently holding
	    //       a lock preventing reps from being created
	    (*((RegionRef)getRef()))->destroy(); // destroy ourselves
	    regionState = DESTROYING;
	    return rc;
	}
    } else {
	fcm = NULL;
    }

    // If ok, attach the region to the process
    // attach newly contructed region to process
    if (useVaddr) {
	rc = DREF(pRef)->attachFixedRegion(
	    regionVaddr, regionSize, (RegionRef)getRef(), regionType);
    } else if (vaddr2 == 0) {
	// alignment fix up for shared segments
	if(size >= SEGMENT_SIZE && alignment == 0 && !useVaddr &&
	   fcm && DREF(fcm)->sharedSegments()) {
	    alignment = SEGMENT_SIZE;
	}

	rc = DREF(pRef)->attachDynamicRegion(
	    regionVaddr, regionSize, (RegionRef)getRef(), regionType, alignment);
	// return address allocated by process
	vaddr = regionVaddr;
    } else {
	rc = DREF(pRef)->attachWithinRangeRegion(
	    vaddr, vaddr2, regionSize, (RegionRef)getRef(), regionType, alignment);
	regionVaddr = vaddr;
    }

    if (!_SUCCESS(rc)) {
	// failed - delete it
	tassert(0,err_printf("Region constructor failed\n"));
	if (fcm != NULL) {
	    DREF(fcm)->detachRegion((RegionRef)getRef());
	    fcm = NULL;
	}
	// FIXME we are going to have a problem if we just call destroy
	//       unchecked because that will attempt to create a
	//       rep to call the method on, but we are currently holding
	//       a lock preventing reps from being created
	(*((RegionRef)getRef()))->destroyUnchecked(); // free ref
	regionState = DESTROYING;
	return rc;
    }
    
    // unmap any full segments so shared mappings can be used
    if ((SEGMENT_ROUND_DOWN(vaddr+size)>SEGMENT_ROUND_UP(vaddr)) &&
	fcm && DREF(fcm)->sharedSegments()) {
	rc = DREF(hat)->unmapRange(
	    SEGMENT_ROUND_UP(vaddr),
	    SEGMENT_ROUND_DOWN(vaddr+size)- SEGMENT_ROUND_UP(vaddr),
	    ppset);
	tassert(_SUCCESS(rc), err_printf("oops\n"));
    }
    regionState = NORMAL;
    return rc;
}
예제 #20
0
파일: filesup.c 프로젝트: hoangduit/reactos
NTSTATUS
SetupCopyFile(
    PWCHAR SourceFileName,
    PWCHAR DestinationFileName)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE FileHandleSource;
    HANDLE FileHandleDest;
    static IO_STATUS_BLOCK IoStatusBlock;
    FILE_STANDARD_INFORMATION FileStandard;
    FILE_BASIC_INFORMATION FileBasic;
    ULONG RegionSize;
    UNICODE_STRING FileName;
    NTSTATUS Status;
    PVOID SourceFileMap = 0;
    HANDLE SourceFileSection;
    SIZE_T SourceSectionSize = 0;
    LARGE_INTEGER ByteOffset;

#ifdef __REACTOS__
    RtlInitUnicodeString(&FileName,
                         SourceFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtOpenFile(&FileHandleSource,
                        GENERIC_READ,
                        &ObjectAttributes,
                        &IoStatusBlock,
                        FILE_SHARE_READ,
                        FILE_SEQUENTIAL_ONLY);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName);
        goto done;
    }
#else
    FileHandleSource = CreateFileW(SourceFileName,
                                   GENERIC_READ,
                                   FILE_SHARE_READ,
                                   NULL,
                                   OPEN_EXISTING,
                                   0,
                                   NULL);
    if (FileHandleSource == INVALID_HANDLE_VALUE)
    {
        Status = STATUS_UNSUCCESSFUL;
        goto done;
    }
#endif

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,
                                    &FileStandard,
                                    sizeof(FILE_STANDARD_INFORMATION),
                                    FileStandardInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtQueryInformationFile(FileHandleSource,
                                    &IoStatusBlock,&FileBasic,
                                    sizeof(FILE_BASIC_INFORMATION),
                                    FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtQueryInformationFile failed: %x\n", Status);
        goto closesrc;
    }

    Status = NtCreateSection(&SourceFileSection,
                             SECTION_MAP_READ,
                             NULL,
                             NULL,
                             PAGE_READONLY,
                             SEC_COMMIT,
                             FileHandleSource);
    if (!NT_SUCCESS(Status))
    {
      DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName);
      goto closesrc;
    }

    Status = NtMapViewOfSection(SourceFileSection,
                                NtCurrentProcess(),
                                &SourceFileMap,
                                0,
                                0,
                                NULL,
                                &SourceSectionSize,
                                ViewUnmap,
                                0,
                                PAGE_READONLY );
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName);
        goto closesrcsec;
    }

    RtlInitUnicodeString(&FileName,
                         DestinationFileName);

    InitializeObjectAttributes(&ObjectAttributes,
                               &FileName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtCreateFile(&FileHandleDest,
                          GENERIC_WRITE | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          NULL,
                          FILE_ATTRIBUTE_NORMAL,
                          0,
                          FILE_OVERWRITE_IF,
                          FILE_NO_INTERMEDIATE_BUFFERING |
                          FILE_SEQUENTIAL_ONLY |
                          FILE_SYNCHRONOUS_IO_NONALERT,
                          NULL,
                          0);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtCreateFile failed: %x\n", Status);
        goto unmapsrcsec;
    }

    RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
    IoStatusBlock.Status = 0;
    ByteOffset.QuadPart = 0;
    Status = NtWriteFile(FileHandleDest,
                         NULL,
                         NULL,
                         NULL,
                         &IoStatusBlock,
                         SourceFileMap,
                         RegionSize,
                         &ByteOffset,
                         NULL);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize);
        goto closedest;
    }

    /* Copy file date/time from source file */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileBasic,
                                  sizeof(FILE_BASIC_INFORMATION),
                                  FileBasicInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
        goto closedest;
    }

    /* shorten the file back to it's real size after completing the write */
    Status = NtSetInformationFile(FileHandleDest,
                                  &IoStatusBlock,
                                  &FileStandard.EndOfFile,
                                  sizeof(FILE_END_OF_FILE_INFORMATION),
                                  FileEndOfFileInformation);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtSetInformationFile failed: %x\n", Status);
    }

closedest:
    NtClose(FileHandleDest);

unmapsrcsec:
    NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap);

closesrcsec:
    NtClose(SourceFileSection);

closesrc:
    NtClose(FileHandleSource);

done:
    return Status;
}
예제 #21
0
파일: create.c 프로젝트: RareHare/reactos
NTSTATUS NTAPI
NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
                    PIRP Irp)
{
    PEXTENDED_IO_STACK_LOCATION IoStack;
    PFILE_OBJECT FileObject;
    PNPFS_VCB Vcb;
    PNPFS_FCB Fcb;
    PNPFS_CCB Ccb;
    PNAMED_PIPE_CREATE_PARAMETERS Buffer;

    DPRINT("NpfsCreateNamedPipe(DeviceObject %p Irp %p)\n", DeviceObject, Irp);

    Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
    IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
    FileObject = IoStack->FileObject;
    DPRINT("FileObject %p\n", FileObject);
    DPRINT("Pipe name %wZ\n", &FileObject->FileName);

    Buffer = IoStack->Parameters.CreatePipe.Parameters;

    Irp->IoStatus.Information = 0;

    if (!(IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) ||
        (IoStack->Parameters.CreatePipe.ShareAccess & ~(FILE_SHARE_READ|FILE_SHARE_WRITE)))
    {
        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_INVALID_PARAMETER;
    }

    KeLockMutex(&Vcb->PipeListLock);

    /*
    * First search for existing Pipe with the same name.
    */
    Fcb = NpfsFindPipe(Vcb, &FileObject->FileName);
    if (Fcb != NULL)
    {
        /*
        * Found Pipe with the same name. Check if we are
        * allowed to use it.
        */
        KeUnlockMutex(&Vcb->PipeListLock);

        if (Fcb->CurrentInstances >= Fcb->MaximumInstances)
        {
            DPRINT("Out of instances.\n");
            NpfsDereferenceFcb(Fcb);
            Irp->IoStatus.Status = STATUS_INSTANCE_NOT_AVAILABLE;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return STATUS_INSTANCE_NOT_AVAILABLE;
        }

        if (Fcb->MaximumInstances != Buffer->MaximumInstances ||
            Fcb->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart ||
            Fcb->PipeType != Buffer->NamedPipeType)
        {
            DPRINT("Asked for invalid pipe mode.\n");
            NpfsDereferenceFcb(Fcb);
            Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return STATUS_ACCESS_DENIED;
        }
    }
    else
    {
        Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NPFS_FCB), TAG_NPFS_FCB);
        if (Fcb == NULL)
        {
            KeUnlockMutex(&Vcb->PipeListLock);
            Irp->IoStatus.Status = STATUS_NO_MEMORY;
            Irp->IoStatus.Information = 0;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return STATUS_NO_MEMORY;
        }

        Fcb->Type = FCB_PIPE;
        Fcb->Vcb = Vcb;
        Fcb->RefCount = 1;
        Fcb->PipeName.Length = FileObject->FileName.Length;
        Fcb->PipeName.MaximumLength = Fcb->PipeName.Length + sizeof(UNICODE_NULL);
        Fcb->PipeName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
                                                     Fcb->PipeName.MaximumLength,
                                                     TAG_NPFS_NAMEBLOCK);
        if (Fcb->PipeName.Buffer == NULL)
        {
            KeUnlockMutex(&Vcb->PipeListLock);
            ExFreePoolWithTag(Fcb, TAG_NPFS_FCB);
            Irp->IoStatus.Status = STATUS_NO_MEMORY;
            Irp->IoStatus.Information = 0;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return STATUS_NO_MEMORY;
        }

        RtlCopyUnicodeString(&Fcb->PipeName, &FileObject->FileName);

        InitializeListHead(&Fcb->ServerCcbListHead);
        InitializeListHead(&Fcb->ClientCcbListHead);
        InitializeListHead(&Fcb->WaiterListHead);
        KeInitializeMutex(&Fcb->CcbListLock, 0);

        Fcb->PipeType = Buffer->NamedPipeType;
        Fcb->ServerReadMode = Buffer->ReadMode;
        /* MSDN documentation reads that clients always start off in byte mode */
        Fcb->ClientReadMode = FILE_PIPE_BYTE_STREAM_MODE;

        Fcb->CompletionMode = Buffer->CompletionMode;
        switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
        {
        case FILE_SHARE_READ:
            Fcb->PipeConfiguration = FILE_PIPE_OUTBOUND;
            break;
        case FILE_SHARE_WRITE:
            Fcb->PipeConfiguration = FILE_PIPE_INBOUND;
            break;
        case FILE_SHARE_READ|FILE_SHARE_WRITE:
            Fcb->PipeConfiguration = FILE_PIPE_FULL_DUPLEX;
            break;
        }
        Fcb->MaximumInstances = Buffer->MaximumInstances;
        Fcb->CurrentInstances = 0;
        Fcb->TimeOut = Buffer->DefaultTimeout;
        if (!(Fcb->PipeConfiguration & FILE_PIPE_OUTBOUND) ||
            Fcb->PipeConfiguration & FILE_PIPE_FULL_DUPLEX)
        {
            if (Buffer->InboundQuota == 0)
            {
                Fcb->InboundQuota = Vcb->DefaultQuota;
            }
            else
            {
                Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
                if (Fcb->InboundQuota < Vcb->MinQuota)
                {
                    Fcb->InboundQuota = Vcb->MinQuota;
                }
                else if (Fcb->InboundQuota > Vcb->MaxQuota)
                {
                    Fcb->InboundQuota = Vcb->MaxQuota;
                }
            }
        }
        else
        {
            Fcb->InboundQuota = 0;
        }

        if (Fcb->PipeConfiguration & (FILE_PIPE_FULL_DUPLEX|FILE_PIPE_OUTBOUND))
        {
            if (Buffer->OutboundQuota == 0)
            {
                Fcb->OutboundQuota = Vcb->DefaultQuota;
            }
            else
            {
                Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
                if (Fcb->OutboundQuota < Vcb->MinQuota)
                {
                    Fcb->OutboundQuota = Vcb->MinQuota;
                }
                else if (Fcb->OutboundQuota > Vcb->MaxQuota)
                {
                    Fcb->OutboundQuota = Vcb->MaxQuota;
                }
            }
        }
        else
        {
            Fcb->OutboundQuota = 0;
        }

        InsertTailList(&Vcb->PipeListHead, &Fcb->PipeListEntry);
        KeUnlockMutex(&Vcb->PipeListLock);
    }

    Ccb = NpfsAllocateCcb(CCB_PIPE, Fcb);
    if (Ccb == NULL)
    {
        NpfsDereferenceFcb(Fcb);
        Irp->IoStatus.Status = STATUS_NO_MEMORY;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_NO_MEMORY;
    }

    Ccb->Thread = (struct ETHREAD *)Irp->Tail.Overlay.Thread;

    if (Fcb->InboundQuota)
    {
        Ccb->Data = ExAllocatePoolWithTag(PagedPool,
                                          Fcb->InboundQuota,
                                          TAG_NPFS_CCB_DATA);
        if (Ccb->Data == NULL)
        {
            NpfsDereferenceCcb(Ccb);
            NpfsDereferenceFcb(Fcb);

            Irp->IoStatus.Status = STATUS_NO_MEMORY;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return STATUS_NO_MEMORY;
        }
    }
    else
    {
        Ccb->Data = NULL;
    }

    Ccb->ReadPtr = Ccb->Data;
    Ccb->WritePtr = Ccb->Data;
    Ccb->ReadDataAvailable = 0;
    Ccb->WriteQuotaAvailable = Fcb->InboundQuota;
    Ccb->MaxDataLength = Fcb->InboundQuota;
    InitializeListHead(&Ccb->ReadRequestListHead);
    ExInitializeFastMutex(&Ccb->DataListLock);

    Fcb->CurrentInstances++;

    Ccb->Fcb = Fcb;
    Ccb->FileObject = FileObject;
    Ccb->PipeEnd = FILE_PIPE_SERVER_END;
    Ccb->PipeState = FILE_PIPE_LISTENING_STATE;

    DPRINT("CCB: %p\n", Ccb);

    KeInitializeEvent(&Ccb->ConnectEvent, SynchronizationEvent, FALSE);
    KeInitializeEvent(&Ccb->ReadEvent, NotificationEvent, FALSE);
    KeInitializeEvent(&Ccb->WriteEvent, NotificationEvent, FALSE);

    KeLockMutex(&Fcb->CcbListLock);
    InsertTailList(&Fcb->ServerCcbListHead, &Ccb->CcbListEntry);
    KeUnlockMutex(&Fcb->CcbListLock);

    FileObject->FsContext = Fcb;
    FileObject->FsContext2 = Ccb;
    FileObject->Flags |= FO_NAMED_PIPE;

    Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DPRINT("Success!\n");

    return STATUS_SUCCESS;
}