Process* ProcessManager::CreateProcess(char* appname, UINT32 processType) { FILE file; /* open file */ file = volOpenFile(appname); if (file.flags == FS_INVALID) return 0; if ((file.flags & FS_DIRECTORY) == FS_DIRECTORY) return 0; pdirectory* addressSpace = 0; addressSpace = vmmngr_createAddressSpace(); if (!addressSpace) { volCloseFile(&file); return 0; } mapKernelSpace(addressSpace); Process* pProcess = new Process(); pProcess->TaskID = ProcessManager::GetInstance()->GetNextProcessId(); pProcess->pPageDirectory = addressSpace; pProcess->dwPriority = 1; pProcess->dwRunState = PROCESS_STATE_ACTIVE; Thread* pThread = CreateThread(pProcess, &file); List_Add(&pProcess->pThreadQueue, "", pThread); return pProcess; }
Thread* ProcessManager::CreateThread(Process* pProcess, FILE* file) { unsigned char buf[512]; IMAGE_DOS_HEADER* dosHeader = 0; IMAGE_NT_HEADERS* ntHeaders = 0; unsigned char* memory = 0; /* read 512 bytes into buffer */ volReadFile(file, buf, 512); if (!validateImage(buf)) { volCloseFile(file); return 0; } dosHeader = (IMAGE_DOS_HEADER*)buf; ntHeaders = (IMAGE_NT_HEADERS*)(dosHeader->e_lfanew + (uint32_t)buf); Thread* pThread = new Thread(); pThread->pParent = pProcess; pThread->kernelStack = 0; pThread->priority = 1; pThread->state = PROCESS_STATE_ACTIVE; pThread->initialStack = 0; pThread->stackLimit = (void*)((uint32_t)pThread->initialStack + 4096); pThread->imageBase = ntHeaders->OptionalHeader.ImageBase; pThread->imageSize = ntHeaders->OptionalHeader.SizeOfImage; memset(&pThread->frame, 0, sizeof(trapFrame)); pThread->frame.eip = (uint32_t)ntHeaders->OptionalHeader.AddressOfEntryPoint + ntHeaders->OptionalHeader.ImageBase; pThread->frame.flags = 0x200; int pageRest = 0; if ((pThread->imageSize % 4096) > 0) pageRest = 1; pProcess->dwPageCount = (pThread->imageSize / 4096) + pageRest; memory = (unsigned char*)pmmngr_alloc_blocks(pProcess->dwPageCount); /* map page into address space */ for (int i = 0; i <pProcess->dwPageCount; i++) { //DebugPrintf("\ndsfdsd"); vmmngr_mapPhysicalAddress(pProcess->pPageDirectory, ntHeaders->OptionalHeader.ImageBase + i * 4096, (uint32_t)memory + i * 4096, I86_PTE_PRESENT | I86_PTE_WRITABLE | I86_PTE_USER); } memset(memory, 0, pThread->imageSize); memcpy(memory, buf, 512); /* load image into memory */ int fileRest = 0; if ((pThread->imageSize % 512) != 0) fileRest = 1; int readCount = (pThread->imageSize / 512) + fileRest; for (int i = 1; i < readCount; i++) { if (file->eof == 1) break; volReadFile(file, memory + 512 * i, 512); } /* close file and return process ID */ volCloseFile(file); /* Create userspace stack (process esp=0x100000) */ void* stack = (void*)(ntHeaders->OptionalHeader.ImageBase + ntHeaders->OptionalHeader.SizeOfImage + PAGE_SIZE); void* stackPhys = (void*)pmmngr_alloc_block(); /* map user process stack space */ vmmngr_mapPhysicalAddress(pProcess->pPageDirectory, (uint32_t)stack, (uint32_t)stackPhys, I86_PTE_PRESENT | I86_PTE_WRITABLE | I86_PTE_USER); /* Create Heap*/ /* final initialization */ pThread->initialStack = stack; pThread->frame.esp = (uint32_t)pThread->initialStack; pThread->frame.ebp = pThread->frame.esp; //DebugPrintf("\nThread Creation Success"); return pThread; }
/** * Create process * \param appname Application file name * \ret Status code */ int createProcess (char* appname) { IMAGE_DOS_HEADER* dosHeader = 0; IMAGE_NT_HEADERS* ntHeaders = 0; FILE file; pdirectory* addressSpace = 0; process* proc = 0; thread* mainThread = 0; unsigned char* memory = 0; unsigned char buf[512]; uint32_t i = 0; /* open file */ file = volOpenFile (appname); if (file.flags == FS_INVALID) return 0; if (( file.flags & FS_DIRECTORY ) == FS_DIRECTORY) return 0; /* read 512 bytes into buffer */ volReadFile ( &file, buf, 512); if (! validateImage (buf)) { volCloseFile ( &file ); return 0; } dosHeader = (IMAGE_DOS_HEADER*)buf; ntHeaders = (IMAGE_NT_HEADERS*)(dosHeader->e_lfanew + (uint32_t)buf); /* get process virtual address space */ // addressSpace = vmmngr_createAddressSpace (); addressSpace = vmmngr_get_directory (); if (!addressSpace) { volCloseFile (&file); return 0; } /* map kernel space into process address space. Only needed if creating new address space */ //mapKernelSpace (addressSpace); /* create PCB */ proc = getCurrentProcess(); proc->id = 1; proc->pageDirectory = addressSpace; proc->priority = 1; proc->state = PROCESS_STATE_ACTIVE; proc->threadCount = 1; /* create thread descriptor */ mainThread = &proc->threads[0]; mainThread->kernelStack = 0; mainThread->parent = proc; mainThread->priority = 1; mainThread->state = PROCESS_STATE_ACTIVE; mainThread->initialStack = 0; mainThread->stackLimit = (void*) ((uint32_t) mainThread->initialStack + 4096); mainThread->imageBase = ntHeaders->OptionalHeader.ImageBase; mainThread->imageSize = ntHeaders->OptionalHeader.SizeOfImage; memset (&mainThread->frame, 0, sizeof (trapFrame)); mainThread->frame.eip = ntHeaders->OptionalHeader.AddressOfEntryPoint + ntHeaders->OptionalHeader.ImageBase; mainThread->frame.flags = 0x200; /* copy our 512 block read above and rest of 4k block */ memory = (unsigned char*)pmmngr_alloc_block(); memset (memory, 0, 4096); memcpy (memory, buf, 512); /* load image into memory */ for (i=1; i <= mainThread->imageSize/512; i++) { if (file.eof == 1) break; volReadFile ( &file, memory+512*i, 512); } /* map page into address space */ vmmngr_mapPhysicalAddress (proc->pageDirectory, ntHeaders->OptionalHeader.ImageBase, (uint32_t) memory, I86_PTE_PRESENT|I86_PTE_WRITABLE|I86_PTE_USER); /* load and map rest of image */ i = 1; while (file.eof != 1) { /* allocate new frame */ unsigned char* cur = (unsigned char*)pmmngr_alloc_block(); /* read block */ int curBlock = 0; for (curBlock = 0; curBlock < 8; curBlock++) { if (file.eof == 1) break; volReadFile ( &file, cur+512*curBlock, 512); } /* map page into process address space */ vmmngr_mapPhysicalAddress (proc->pageDirectory, ntHeaders->OptionalHeader.ImageBase + i*4096, (uint32_t) cur, I86_PTE_PRESENT|I86_PTE_WRITABLE|I86_PTE_USER); i++; } /* Create userspace stack (process esp=0x100000) */ void* stack = (void*) (ntHeaders->OptionalHeader.ImageBase + ntHeaders->OptionalHeader.SizeOfImage + PAGE_SIZE); void* stackPhys = (void*) pmmngr_alloc_block (); /* map user process stack space */ vmmngr_mapPhysicalAddress (addressSpace, (uint32_t) stack, (uint32_t) stackPhys, I86_PTE_PRESENT|I86_PTE_WRITABLE|I86_PTE_USER); /* final initialization */ mainThread->initialStack = stack; mainThread->frame.esp = (uint32_t)mainThread->initialStack; mainThread->frame.ebp = mainThread->frame.esp; /* close file and return process ID */ volCloseFile(&file); return proc->id; }