/** * Finds the files in the directory that currently has focus. * * Parameters * llelement **head * This is the value of the current location of the head of the linked list. This * is only passed in here so we can pass it on to InsertIntoList. * llelement **tail * This is the value of the current location of the tail of the linked list. This * is only passed in here so we can pass it on to InsertIntoList. * * Returns * 0 if we successfully found all the files and added them to the list */ int FindFiles(llelement **head, llelement **tail) { int validatorInt = 0; char *name; void *p = NULL; fileData *pFileData = NULL; WIN32_FIND_DATA FindFileData; /* When we find a file, this is populated with that files data */ HANDLE hFind; /* Handle to the file */ hFind = FindFirstFile("*", &FindFileData); if (INVALID_HANDLE_VALUE == hFind) { printf ("FindFirstFile failed (%d)\n", GetLastError()); return -1; } do { p = AllocateSpace(sizeof(pFileData)); pFileData = (fileData*)GetDataAddress(p); pFileData->name = (char *)malloc(sizeof(FindFileData.cFileName)); strcpy_s(pFileData->name, MAX_BUFFER_SIZE, FindFileData.cFileName); /* Copy the filename into the struct we are going to insert */ validatorInt = InsertIntoList((llelement *)p, head, tail); /* Insert the file we found into the list */ if(0 != validatorInt) { printf("Could not store file in memory."); return -1; } } while (0 != FindNextFile(hFind, &FindFileData)); return 0; }
int main() { ListNode *head = NULL; InsertIntoList( &head, 7 ); InsertIntoList( &head, 3 ); InsertIntoList( &head, 5 ); InsertIntoList( &head, 1 ); InsertIntoList( &head, 2 ); InsertIntoList( &head, 4 ); head = SeparateElements( head, 3 ); printf("\n"); while( head ) { printf("\t %d", head->data ); head = head->next; } return 0; }
// //DoIoMap routine.When VirtualAlloc is called with VIRTUAL_AREA_ALLOCATE_IO, //then is routine is called by VirtualAlloc. // static LPVOID DoIoMap(__COMMON_OBJECT* lpThis, LPVOID lpDesiredAddr, DWORD dwSize, DWORD dwAllocFlags, DWORD dwAccessFlags, UCHAR* lpVaName, LPVOID lpReserved) { __VIRTUAL_AREA_DESCRIPTOR* lpVad = NULL; __VIRTUAL_MEMORY_MANAGER* lpMemMgr = (__VIRTUAL_MEMORY_MANAGER*)lpThis; LPVOID lpStartAddr = lpDesiredAddr; LPVOID lpEndAddr = NULL; DWORD dwFlags = 0; BOOL bResult = FALSE; LPVOID lpPhysical = NULL; __PAGE_INDEX_MANAGER* lpIndexMgr = NULL; DWORD dwPteFlags = 0; if((NULL == lpThis) || (0 == dwSize)) //Parameter check. return NULL; if(VIRTUAL_AREA_ALLOCATE_IO != dwAllocFlags) //Invalidate flags. return NULL; lpIndexMgr = lpMemMgr->lpPageIndexMgr; if(NULL == lpIndexMgr) //Validate. return NULL; lpStartAddr = (LPVOID)((DWORD)lpStartAddr & ~(PAGE_FRAME_SIZE - 1)); //Round up to page. lpEndAddr = (LPVOID)((DWORD)lpDesiredAddr + dwSize ); lpEndAddr = (LPVOID)(((DWORD)lpEndAddr & (PAGE_FRAME_SIZE - 1)) ? (((DWORD)lpEndAddr & ~(PAGE_FRAME_SIZE - 1)) + PAGE_FRAME_SIZE - 1) : ((DWORD)lpEndAddr - 1)); //Round down to page. dwSize = (DWORD)lpEndAddr - (DWORD)lpStartAddr + 1; //Get the actually size. lpVad = (__VIRTUAL_AREA_DESCRIPTOR*)KMemAlloc(sizeof(__VIRTUAL_AREA_DESCRIPTOR), KMEM_SIZE_TYPE_ANY); //In order to avoid calling KMemAlloc routine in the //critical section,we first call it here. if(NULL == lpVad) //Can not allocate memory. goto __TERMINAL; lpVad->lpManager = lpMemMgr; lpVad->lpStartAddr = NULL; lpVad->lpEndAddr = NULL; lpVad->lpNext = NULL; lpVad->dwAccessFlags = dwAccessFlags; lpVad->dwAllocFlags = dwAllocFlags; __INIT_ATOMIC(lpVad->Reference); lpVad->lpLeft = NULL; lpVad->lpRight = NULL; if(lpVaName) { if(StrLen((LPSTR)lpVaName) > MAX_VA_NAME_LEN) lpVaName[MAX_VA_NAME_LEN - 1] = 0; StrCpy((LPSTR)lpVad->strName[0],(LPSTR)lpVaName); //Set the virtual area's name. } else lpVad->strName[0] = 0; lpVad->dwCacheFlags = VIRTUAL_AREA_CACHE_IO; // //The following code searchs virtual area list or AVL tree,to check if the lpDesiredAddr //is occupied,if so,then find a new one. // __ENTER_CRITICAL_SECTION(NULL,dwFlags); if(lpMemMgr->dwVirtualAreaNum < SWITCH_VA_NUM) //Should search in the list. lpStartAddr = SearchVirtualArea_l((__COMMON_OBJECT*)lpMemMgr,lpStartAddr,dwSize); else //Should search in the AVL tree. lpStartAddr = SearchVirtualArea_t((__COMMON_OBJECT*)lpMemMgr,lpStartAddr,dwSize); if(NULL == lpStartAddr) //Can not find proper virtual area. { __LEAVE_CRITICAL_SECTION(NULL,dwFlags); goto __TERMINAL; } lpVad->lpStartAddr = lpStartAddr; lpVad->lpEndAddr = (LPVOID)((DWORD)lpStartAddr + dwSize -1); lpDesiredAddr = lpStartAddr; if(lpMemMgr->dwVirtualAreaNum < SWITCH_VA_NUM) InsertIntoList((__COMMON_OBJECT*)lpMemMgr,lpVad); //Insert into list or tree. else InsertIntoTree((__COMMON_OBJECT*)lpMemMgr,lpVad); // //The following code reserves page table entries for the committed memory. // dwPteFlags = PTE_FLAGS_FOR_IOMAP; //IO map flags,that is,this memory range will not //use hardware cache. lpPhysical = lpStartAddr; while(dwSize) { if(!lpIndexMgr->ReservePage((__COMMON_OBJECT*)lpIndexMgr, lpStartAddr,lpPhysical,dwPteFlags)) { PrintLine("Fatal Error : Internal data structure is not consist."); __LEAVE_CRITICAL_SECTION(NULL,dwFlags); goto __TERMINAL; } dwSize -= PAGE_FRAME_SIZE; lpStartAddr = (LPVOID)((DWORD)lpStartAddr + PAGE_FRAME_SIZE); lpPhysical = (LPVOID)((DWORD)lpPhysical + PAGE_FRAME_SIZE); } __LEAVE_CRITICAL_SECTION(NULL,dwFlags); bResult = TRUE; //Indicate that the whole operation is successfully. __TERMINAL: if(!bResult) //Process failed. { if(lpVad) KMemFree((LPVOID)lpVad,KMEM_SIZE_TYPE_ANY,0); if(lpPhysical) PageFrameManager.FrameFree((__COMMON_OBJECT*)&PageFrameManager, lpPhysical, dwSize); return NULL; } return lpDesiredAddr; }
BOOL VmmInitialize(__COMMON_OBJECT* lpThis) { __VIRTUAL_MEMORY_MANAGER* lpManager = NULL; __PAGE_INDEX_MANAGER* lpPageIndexMgr = NULL; __VIRTUAL_AREA_DESCRIPTOR* lpVad = NULL; BOOL bResult = FALSE; if(NULL == lpThis) //Parameter check. { return FALSE; } lpManager = (__VIRTUAL_MEMORY_MANAGER*)lpThis; lpManager->VirtualAlloc = kVirtualAlloc; lpManager->VirtualFree = kVirtualFree; lpManager->GetPdAddress = GetPdAddress; lpManager->dwVirtualAreaNum = 0; // //The following code creates the page index manager object. // lpPageIndexMgr = (__PAGE_INDEX_MANAGER*)ObjectManager.CreateObject(&ObjectManager, NULL, OBJECT_TYPE_PAGE_INDEX_MANAGER); if(NULL == lpPageIndexMgr) //Failed to create the page index manager object. { goto __TERMINAL; } if(!lpPageIndexMgr->Initialize((__COMMON_OBJECT*)lpPageIndexMgr)) //Can not initialize. { ObjectManager.DestroyObject(&ObjectManager, (__COMMON_OBJECT*)lpPageIndexMgr); lpPageIndexMgr = NULL; goto __TERMINAL; } lpManager->lpPageIndexMgr = lpPageIndexMgr; lpVad = (__VIRTUAL_AREA_DESCRIPTOR*)KMemAlloc(sizeof(__VIRTUAL_AREA_DESCRIPTOR), KMEM_SIZE_TYPE_ANY); if(NULL == lpVad) goto __TERMINAL; #define SET(member,value) lpVad->member = value SET(lpManager, lpManager); SET(lpStartAddr, VIRTUAL_MEMORY_KERNEL_START); SET(lpEndAddr, (LPVOID)VIRTUAL_MEMORY_KERNEL_END); SET(lpNext, NULL); SET(dwAccessFlags, VIRTUAL_AREA_ACCESS_RW); SET(dwAllocFlags, VIRTUAL_AREA_ALLOCATE_COMMIT); SET(lpLeft, NULL); SET(lpRight, NULL); SET(dwCacheFlags, VIRTUAL_AREA_CACHE_NORMAL); #undef SET __INIT_ATOMIC(lpVad->Reference); StrCpy((LPSTR)"System Kernel",(LPSTR)&lpVad->strName[0]); // //Insert the system kernel area into virtual memory manager's list. // InsertIntoList((__COMMON_OBJECT*)lpManager,lpVad); bResult = TRUE; //Commit the whole transaction. __TERMINAL: if(!bResult) { if(lpPageIndexMgr) ObjectManager.DestroyObject(&ObjectManager, (__COMMON_OBJECT*)lpPageIndexMgr); //Destroy the page index manager object. if(lpVad) KMemFree((LPVOID)lpVad,KMEM_SIZE_TYPE_ANY,0); //Free memory. return FALSE; } return TRUE; }
// //DoReserve routine.When VirtualAlloc is called with VIRTUAL_AREA_ALLOCATE_RESERVE, //then is routine is called by VirtualAlloc. // static LPVOID DoReserve(__COMMON_OBJECT* lpThis, LPVOID lpDesiredAddr, DWORD dwSize, DWORD dwAllocFlags, DWORD dwAccessFlags, UCHAR* lpVaName, LPVOID lpReserved) { __VIRTUAL_AREA_DESCRIPTOR* lpVad = NULL; __VIRTUAL_MEMORY_MANAGER* lpMemMgr = (__VIRTUAL_MEMORY_MANAGER*)lpThis; LPVOID lpStartAddr = lpDesiredAddr; LPVOID lpEndAddr = NULL; DWORD dwFlags = 0; BOOL bResult = FALSE; LPVOID lpPhysical = NULL; __PAGE_INDEX_MANAGER* lpIndexMgr = NULL; DWORD dwPteFlags = 0; if((NULL == lpThis) || (0 == dwSize)) //Parameter check. return NULL; if(VIRTUAL_AREA_ALLOCATE_RESERVE != dwAllocFlags) //Invalidate flags. return NULL; lpIndexMgr = lpMemMgr->lpPageIndexMgr; if(NULL == lpIndexMgr) //Validate. return NULL; lpStartAddr = (LPVOID)((DWORD)lpStartAddr & ~(PAGE_FRAME_SIZE - 1)); //Round up to page. lpEndAddr = (LPVOID)((DWORD)lpDesiredAddr + dwSize ); lpEndAddr = (LPVOID)(((DWORD)lpEndAddr & (PAGE_FRAME_SIZE - 1)) ? (((DWORD)lpEndAddr & ~(PAGE_FRAME_SIZE - 1)) + PAGE_FRAME_SIZE - 1) : ((DWORD)lpEndAddr - 1)); //Round down to page. dwSize = (DWORD)lpEndAddr - (DWORD)lpStartAddr + 1; //Get the actually size. lpVad = (__VIRTUAL_AREA_DESCRIPTOR*)KMemAlloc(sizeof(__VIRTUAL_AREA_DESCRIPTOR), KMEM_SIZE_TYPE_ANY); //In order to avoid calling KMemAlloc routine in the //critical section,we first call it here. if(NULL == lpVad) //Can not allocate memory. goto __TERMINAL; lpVad->lpManager = lpMemMgr; lpVad->lpStartAddr = NULL; lpVad->lpEndAddr = NULL; lpVad->lpNext = NULL; lpVad->dwAccessFlags = dwAccessFlags; lpVad->dwAllocFlags = dwAllocFlags; __INIT_ATOMIC(lpVad->Reference); lpVad->lpLeft = NULL; lpVad->lpRight = NULL; if(lpVaName) { if(StrLen((LPSTR)lpVaName) > MAX_VA_NAME_LEN) lpVaName[MAX_VA_NAME_LEN - 1] = 0; StrCpy((LPSTR)lpVad->strName[0],(LPSTR)lpVaName); //Set the virtual area's name. } else lpVad->strName[0] = 0; lpVad->dwCacheFlags = VIRTUAL_AREA_CACHE_NORMAL; // //The following code searchs virtual area list or AVL tree,to check if the lpDesiredAddr //is occupied,if so,then find a new one. // __ENTER_CRITICAL_SECTION(NULL,dwFlags); if(lpMemMgr->dwVirtualAreaNum < SWITCH_VA_NUM) //Should search in the list. lpStartAddr = SearchVirtualArea_l((__COMMON_OBJECT*)lpMemMgr,lpStartAddr,dwSize); else //Should search in the AVL tree. lpStartAddr = SearchVirtualArea_t((__COMMON_OBJECT*)lpMemMgr,lpStartAddr,dwSize); if(NULL == lpStartAddr) //Can not find proper virtual area. { __LEAVE_CRITICAL_SECTION(NULL,dwFlags); goto __TERMINAL; } lpVad->lpStartAddr = lpStartAddr; lpVad->lpEndAddr = (LPVOID)((DWORD)lpStartAddr + dwSize -1); lpDesiredAddr = lpStartAddr; if(lpMemMgr->dwVirtualAreaNum < SWITCH_VA_NUM) InsertIntoList((__COMMON_OBJECT*)lpMemMgr,lpVad); //Insert into list or tree. else InsertIntoTree((__COMMON_OBJECT*)lpMemMgr,lpVad); __LEAVE_CRITICAL_SECTION(NULL,dwFlags); bResult = TRUE; //Indicate that the whole operation is successfully. //In this operation(only reserve),we do not commit page table entries, //so,if access the memory space(read or write) of this range,will //cause a page fault exception. //The caller must call VirtualAlloc routine again to commit this //block of area before access it. __TERMINAL: if(!bResult) //Process failed. { if(lpVad) KMemFree((LPVOID)lpVad,KMEM_SIZE_TYPE_ANY,0); if(lpPhysical) PageFrameManager.FrameFree((__COMMON_OBJECT*)&PageFrameManager, lpPhysical, dwSize); return NULL; } return lpDesiredAddr; }