//Add one ethernet interface to the network protocol.The state of the //layer3 interface will be returned and be saved into pEthInt object. LPVOID lwipAddEthernetInterface(__ETHERNET_INTERFACE* pEthInt) { static int ifIndex = 0; struct netif* pIf = NULL; ip_addr_t ipAddr, ipMask, ipGw; //Allocate layer 3 interface for this ethernet interface. pIf = (struct netif*)KMemAlloc(sizeof(struct netif), KMEM_SIZE_TYPE_ANY); if (NULL == pIf) { _hx_printf(" Allocate netif failed.\r\n"); return NULL; } memset(pIf, 0, sizeof(struct netif)); pIf->state = pEthInt; //Point to the layer 2 interface. //Initialize name of layer 3 interface,since it only occupies 2 bytes. pIf->name[0] = pEthInt->ethName[0]; pIf->name[1] = pEthInt->ethName[1]; //Convert common network address to IPv4 address. ipAddr.addr = pEthInt->ifState.IpConfig.ipaddr.Address.ipv4_addr; ipMask.addr = pEthInt->ifState.IpConfig.mask.Address.ipv4_addr; ipGw.addr = pEthInt->ifState.IpConfig.mask.Address.ipv4_addr; //Add the netif to lwIP. netif_add(pIf, &ipAddr, &ipMask,&ipGw,pEthInt,_ethernet_if_init, &tcpip_input); if (0 == ifIndex) { netif_set_default(pIf); ifIndex += 1; } return pIf; }
//Delete a subdirectory in a given directory. BOOL DeleteFatDir(__FAT32_FS* pFat32Fs,CHAR* pszFileName) { __FAT32_SHORTENTRY ShortEntry; __FAT32_SHORTENTRY* pFileEntry = NULL; DWORD dwParentClus = 0; DWORD dwParentOffset = 0; DWORD dwStartClus = 0; DWORD dwSector = 0; BOOL bResult = FALSE; BYTE* pBuffer = NULL; if(!GetDirEntry(pFat32Fs, pszFileName, &ShortEntry, &dwParentClus, //Parent directory's cluster where this entry resides. &dwParentOffset)) //Cluster offset. { goto __TERMINAL; } if(0 == (FILE_ATTR_DIRECTORY & ShortEntry.FileAttributes)) //Not a directory. { goto __TERMINAL; } //Remove the directory entry in it's parent directory. pBuffer = (BYTE*)KMemAlloc(pFat32Fs->dwClusterSize,KMEM_SIZE_TYPE_ANY); if(NULL == pBuffer) { goto __TERMINAL; } dwSector = GetClusterSector(pFat32Fs,dwParentClus); if(0 == dwSector) { goto __TERMINAL; } if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, pFat32Fs->SectorPerClus, pBuffer)) { goto __TERMINAL; } pFileEntry = (__FAT32_SHORTENTRY*)(pBuffer + dwParentOffset); memzero(pFileEntry,sizeof(__FAT32_SHORTENTRY)); pFileEntry->FileName[0] = (CHAR)0xE5; //Empty this short entry. if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, pFat32Fs->SectorPerClus, pBuffer)) { goto __TERMINAL; } bResult = TRUE; __TERMINAL: if(pBuffer) { KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0); } return bResult; }
//Create a BRUSH object. HANDLE CreateBrush(BOOL bTransparent,__COLOR color) { __BRUSH* pBrush = (__BRUSH*)KMemAlloc(sizeof(__BRUSH),KMEM_SIZE_TYPE_ANY); if(NULL == pBrush) { return NULL; } pBrush->bTransparent = bTransparent; pBrush->color = color; return (HANDLE)pBrush; }
static void ping_recv(int s) { char* buf = NULL; int fromlen, len; struct sockaddr_in from; struct ip_hdr *iphdr; struct icmp_echo_hdr *iecho; int ms; BOOL bResult = FALSE; //Allocate a buffer to contain the received data. buf = (char*)KMemAlloc(1500,KMEM_SIZE_TYPE_ANY); if(NULL == buf) { return; } while((len = lwip_recvfrom(s, buf, 1500, 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) { if(len >= (int)(sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) { ip_addr_t fromaddr; inet_addr_to_ipaddr(&fromaddr, &from.sin_addr); //Get times between sent and receive. ms = sys_now() - ping_time; ms *= SYSTEM_TIME_SLICE; iphdr = (struct ip_hdr *)buf; iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); if (((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num)) && iecho->type == ICMP_ER)) { len = len - sizeof(struct ip_hdr) - sizeof(struct icmp_echo_hdr); //Adjust received data's length,since it //includes IP and ICMP headers. _hx_printf(" [%d] Reply from %s,size = %d,time = %d(ms)\r\n",ping_pkt_seq,inet_ntoa(fromaddr),len,ms); ping_succ ++; bResult = TRUE; } else { //printf(" ping : Received invalid replay,drop it.\r\n"); } } } if (!bResult) { _hx_printf(" [%d] Request time out.\r\n",ping_pkt_seq); } if(buf) //Release it. { KMemFree(buf,KMEM_SIZE_TYPE_ANY,0); } }
HISOBJ His_CreateHisObj(INT nHisCount) { HISTORY_CMD_INFO* pHisInfo = NULL; if(nHisCount <= 0) { return NULL; } pHisInfo = (HISTORY_CMD_INFO*)KMemAlloc(sizeof(HISTORY_CMD_INFO),KMEM_SIZE_TYPE_ANY); if(NULL == pHisInfo) { return NULL; } pHisInfo->nHisCount = nHisCount; pHisInfo->nSaveCount = 0; pHisInfo->nExecHisPos = -1; pHisInfo->pHisCmdArry = (HIS_CMD_OBJ*)KMemAlloc(sizeof(HIS_CMD_OBJ)*nHisCount,KMEM_SIZE_TYPE_ANY); return (HISOBJ)pHisInfo; }
//Create a PEN object. HANDLE CreatePen(DWORD type,int width,__COLOR color) { __PEN* pPen = (__PEN*)KMemAlloc(sizeof(__PEN),KMEM_SIZE_TYPE_ANY); if(NULL == pPen) { return NULL; } pPen->type = type; pPen->width = width; pPen->color = color; return (HANDLE)pPen; }
static void Logk(__DEBUG_MANAGER *pThis, char *tag, char *msg) { __DEBUG_MANAGER *pDebugManager = pThis; __LOG_MESSAGE *pMsg = NULL; __KERNEL_THREAD_OBJECT *lpCurrentThread = NULL; int Result = -1; int dwFlags = 0; pMsg = (__LOG_MESSAGE *)KMemAlloc(sizeof(__LOG_MESSAGE),KMEM_SIZE_TYPE_ANY); // //Set to default now // pMsg->code = 0; pMsg->format = 0; pMsg->len = 0; pMsg->pid = 0; pMsg->time = 0; // //*****XXX******* // FIXME // __ENTER_CRITICAL_SECTION(NULL, dwFlags); lpCurrentThread = KernelThreadManager.lpCurrentKernelThread; StrCpy(lpCurrentThread->KernelThreadName,pMsg->name); pMsg->tid = lpCurrentThread->dwThreadID; __LEAVE_CRITICAL_SECTION(NULL, dwFlags); StrCpy(msg, pMsg->msg); StrCpy(tag, pMsg->tag); // //Get the authority to visit the bufferqueue // Result = pDebugManager->pMutexForKRNLBufferQueue->WaitForThisObject((__COMMON_OBJECT*)DebugManager.pMutexForKRNLBufferQueue); if (Result == OBJECT_WAIT_RESOURCE) { pDebugManager->pKRNLBufferQueue->Enqueue( pDebugManager->pKRNLBufferQueue, pMsg); pDebugManager->pMutexForKRNLBufferQueue->ReleaseMutex((__COMMON_OBJECT*)DebugManager.pMutexForKRNLBufferQueue); } KMemFree(pMsg, KMEM_SIZE_TYPE_ANY, 0); return; }
//Create a FONT object. HANDLE CreateFont(int width,int height,int chspace,int lnspace) { __FONT* pFont = (__FONT*)KMemAlloc(sizeof(__FONT),KMEM_SIZE_TYPE_ANY); if(NULL == pFont) { return NULL; } pFont->width = width; pFont->ascwidth = width / 2; pFont->height = height; pFont->chspace = chspace; pFont->lnspace = lnspace; return (HANDLE)pFont; }
static void Logcat(__DEBUG_MANAGER *pThis, char *buf, int len) { __DEBUG_MANAGER *pDebugManager = pThis; __LOG_MESSAGE *pMsg = NULL; __LOG_MESSAGE *p = NULL; int Result = -1; pMsg = (__LOG_MESSAGE *)KMemAlloc(sizeof(__LOG_MESSAGE),KMEM_SIZE_TYPE_ANY); // // Get the authority to visit the kernel bufferqueue // Result = DebugManager.pMutexForKRNLBufferQueue->WaitForThisObject((__COMMON_OBJECT*)DebugManager.pMutexForKRNLBufferQueue); if (Result == OBJECT_WAIT_RESOURCE) { p = pDebugManager->pKRNLBufferQueue->Dequeue(pDebugManager->pKRNLBufferQueue); pDebugManager->pMutexForKRNLBufferQueue->ReleaseMutex((__COMMON_OBJECT*)DebugManager.pMutexForKRNLBufferQueue); } if(p == NULL) { // // Get the authority to visit the user bufferqueue // Result = DebugManager.pMutexForBufferQueue->WaitForThisObject((__COMMON_OBJECT*)DebugManager.pMutexForBufferQueue); if (Result == OBJECT_WAIT_RESOURCE) { p = pDebugManager->pBufferQueue->Dequeue(pDebugManager->pBufferQueue); pDebugManager->pMutexForBufferQueue->ReleaseMutex((__COMMON_OBJECT*)DebugManager.pMutexForBufferQueue); } } if(p != NULL) { pMsg->pid = p->pid; pMsg->tid = p->tid; pMsg->time = p->time; StrCpy(p->tag, pMsg->tag); StrCpy(p->name, pMsg->name); StrCpy(p->msg, pMsg->msg); _hx_sprintf(buf, "tag:%s name:%s time:%d pid:%d tid:%d msg:%s", pMsg->tag, pMsg->name, pMsg->time, pMsg->pid, pMsg->tid, pMsg->msg); } KMemFree(pMsg, KMEM_SIZE_TYPE_ANY, 0); return; }
//Release one cluster. BOOL ReleaseCluster(__FAT32_FS* pFat32Fs,DWORD dwCluster) { BYTE* pBuffer = NULL; DWORD dwSector = 0; DWORD dwOffset = 0; BOOL bResult = FALSE; if((NULL == pFat32Fs) || (dwCluster < 2) || IS_EOC(dwCluster)) { goto __TERMINAL; } dwSector = dwCluster / 128; if(dwSector > pFat32Fs->dwFatSectorNum) { goto __TERMINAL; } dwSector += pFat32Fs->dwFatBeginSector; dwOffset = (dwCluster - (dwCluster / 128) * 128) * sizeof(DWORD); pBuffer = (BYTE*)KMemAlloc(pFat32Fs->dwBytePerSector,KMEM_SIZE_TYPE_ANY); if(NULL == pBuffer) { goto __TERMINAL; } //Read the fat sector where this cluster's index resides,modify to zero and write it back. if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, 1, pBuffer)) { goto __TERMINAL; } *(DWORD*)(pBuffer + dwOffset) &= 0xF0000000; if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, 1, pBuffer)) { goto __TERMINAL; } //All successfully. bResult = TRUE; __TERMINAL: if(pBuffer) { KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0); } return bResult; }
/* * Condition Variable Functions */ int pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr) { __CONDITION* pCondition = NULL; if(NULL == cond) { return EINVAL; } *cond = (pthread_cond_t)KMemAlloc(sizeof(pthread_cond_t),KMEM_SIZE_TYPE_ANY); if(NULL == *cond) { return EINVAL; } (*cond)->cond = CreateCondition(0); if(NULL == (*cond)->cond) { KMemFree(*cond,KMEM_SIZE_TYPE_ANY,0); return EINVAL; } return S_OK; }
static DWORD memalloc(__CMD_PARA_OBJ* lpCmdObj) { DWORD dwMemSize = 0; LPVOID lpMemAddr = NULL; CHAR strBuffer[16]; if(NULL == lpCmdObj) //Parameter check. return SHELL_CMD_PARSER_FAILED; if(lpCmdObj->byParameterNum < 2) //Not enough parameters. { PrintLine("Please input the memory size to be allocated."); return SHELL_CMD_PARSER_SUCCESS; } if(!Str2Hex(lpCmdObj->Parameter[1],&dwMemSize)) //Invalid size value. { PrintLine("Invalid memory size value."); return SHELL_CMD_PARSER_SUCCESS; } lpMemAddr = KMemAlloc(dwMemSize,KMEM_SIZE_TYPE_ANY); if(NULL == lpMemAddr) //Failed to allocate memory. { PrintLine("Can not allocate memory."); return SHELL_CMD_PARSER_SUCCESS; } Hex2Str((DWORD)lpMemAddr,&strBuffer[4]); //Convert to string. strBuffer[0] = ' '; strBuffer[1] = ' '; strBuffer[2] = '0'; strBuffer[3] = 'x'; PrintLine(strBuffer); //Print out the result. return SHELL_CMD_PARSER_SUCCESS; }
//MessageBox routine,to show a message box and get user's input as return. DWORD MessageBox(HANDLE hWnd,TCHAR* pszText,TCHAR* pszTitle,UINT uType) { HANDLE hMsgBoxWnd = NULL; __MESSAGE_BOX* pMsgBox = NULL; int length = 0; int width = 0; BOOL bResult = FALSE; DWORD dwRetVal = 0; __WINDOW_MESSAGE msg; int x,y; //Start position of message box window. __RECT rect; //Parent window's rectangle. if((length = strlen(pszText)) >= MSGBOX_TEXT_LENGTH) //Text too long. { return 0; } pMsgBox = (__MESSAGE_BOX*)KMemAlloc(sizeof(__MESSAGE_BOX),KMEM_SIZE_TYPE_ANY); if(NULL == pMsgBox) { goto __TERMINAL; } strcpy(pMsgBox->MsgBoxText,pszText); pMsgBox->dwMsgBoxType = uType; //Calculate message box's width. if(uType & MB_OK) { width += MSGBOX_BUTTON_SPACE; width += MSGBOX_BUTTON_WIDTH; } if(uType & MB_CANCEL) { width += MSGBOX_BUTTON_SPACE; width += MSGBOX_BUTTON_WIDTH; } if(uType & MB_YES) { width += MSGBOX_BUTTON_SPACE; width += MSGBOX_BUTTON_WIDTH; } if(uType & MB_NO) { width += MSGBOX_BUTTON_SPACE; width += MSGBOX_BUTTON_WIDTH; } width += MSGBOX_BUTTON_SPACE; //Add the left margin between button and window frame. length *= 8; //Calculate the text's space. length += 20; //Reserve 10 pixel between text and window frame. pMsgBox->dwMsgBoxWidth = (length > width) ? length : width; pMsgBox->dwMsgBoxHeight = 100; //Use default height. //Calculate message window's position in screen,default is in it's parent's center. GetWindowRect(hWnd,&rect,GWR_INDICATOR_WINDOW); x = rect.right - rect.left - pMsgBox->dwMsgBoxWidth; y = rect.bottom - rect.top - pMsgBox->dwMsgBoxHeight; x = rect.left + x / 2; y = rect.top + y / 2; if(x < 0) { x = 0; } if(y < 0) { y = 0; } //Create message box window. hMsgBoxWnd = CreateWindow(WS_WITHCAPTION | WS_WITHBORDER, pszTitle, x, y, pMsgBox->dwMsgBoxWidth, pMsgBox->dwMsgBoxHeight, MsgBoxWndProc, hWnd, NULL, GlobalParams.COLOR_BTNFACE, NULL); if(NULL == hMsgBoxWnd) { goto __TERMINAL; } SetWindowExtension(hMsgBoxWnd,pMsgBox); msg.hWnd = hMsgBoxWnd; msg.message = WM_INITDIALOG; msg.lParam = 0; msg.wParam = 0; SendWindowMessage(hMsgBoxWnd,&msg); //Refresh the message box. //Enter the message loop now. dwRetVal = DialogLoop(hMsgBoxWnd); bResult = TRUE; __TERMINAL: if(!bResult) { if(pMsgBox) { KMemFree(pMsgBox,KMEM_SIZE_TYPE_ANY,0); } if(hMsgBoxWnd) { DestroyWindow(hMsgBoxWnd); } } return dwRetVal; }
//Process user input. //This is a private function can only be called by heditEntry. static VOID __UserInput(HANDLE hFile) { #ifdef __CFG_SYS_DDF BYTE* pDataBuffer = NULL; BYTE* pCurrPos = NULL; DWORD dwDefaultSize = 8192; //Default file size is 8K. BOOL bCtrlDown = FALSE; BYTE bt; WORD wr = 0x0700; __KERNEL_THREAD_MESSAGE Msg; DWORD dwWrittenSize = 0; pDataBuffer = (BYTE*)KMemAlloc(dwDefaultSize,KMEM_SIZE_TYPE_ANY); if(NULL == pDataBuffer) { PrintLine(" Can not allocate memory."); goto __TERMINAL; } pCurrPos = pDataBuffer; while(TRUE) { if(GetMessage(&Msg)) { if(MSG_KEY_DOWN == Msg.wCommand) //This is a key down message. { bt = (BYTE)Msg.dwParam; switch(bt) { case VK_RETURN: //This is a return key. if((DWORD)(pCurrPos - pDataBuffer) < dwDefaultSize - 2) { *pCurrPos ++ = '\r'; //Append a return key. *pCurrPos ++ = '\n'; GotoHome(); ChangeLine(); //Change to next line. } break; case VK_BACKSPACE: if(*pCurrPos == '\n') //Enter encountered. { pCurrPos -= 2; //Skip the \r\n. } else { pCurrPos -= 1; } GotoPrev(); break; default: if(('c' == bt) || ('C' == bt) || ('z' == bt) || ('Z' == bt)) { if(bCtrlDown) //CtrlC or CtrlZ encountered. { goto __TERMINAL; } } if((DWORD)(pCurrPos - pDataBuffer) < dwDefaultSize) { *pCurrPos ++ = bt; //Save this character. wr += bt; PrintCh(wr); wr = 0x0700; } break; } } else { if(VIRTUAL_KEY_DOWN == Msg.wCommand) { bt = (BYTE)Msg.dwParam; if(VK_CONTROL == bt) { bCtrlDown = TRUE; } } if(VIRTUAL_KEY_UP == Msg.wCommand) { bt = (BYTE)Msg.dwParam; if(VK_CONTROL == bt) //Control key up. { bCtrlDown = FALSE; } } } } } __TERMINAL: IOManager.WriteFile((__COMMON_OBJECT*)&IOManager, hFile, (DWORD)(pCurrPos - pDataBuffer), pDataBuffer, &dwWrittenSize); if(pDataBuffer) { KMemFree(pDataBuffer,KMEM_SIZE_TYPE_ANY,0); } return; #else #endif }
//Get one free cluster and mark the cluster as used. //If find,TRUE will be returned and the cluster number will be set in pdwFreeCluster, //else FALSE will be returned without any changing to pdwFreeCluster. BOOL GetFreeCluster(__FAT32_FS* pFat32Fs,DWORD dwStartToFind,DWORD* pdwFreeCluster) { DWORD dwCurrCluster = 0; DWORD dwSector = 0; BYTE* pBuffer = NULL; DWORD* pCluster = NULL; BOOL bResult = FALSE; DWORD i; CHAR Buffer[64]; pBuffer = (BYTE*)KMemAlloc(pFat32Fs->dwBytePerSector,KMEM_SIZE_TYPE_ANY); if(NULL == pBuffer) //Can not allocate temporary buffer. { return FALSE; } dwSector = pFat32Fs->dwFatBeginSector; while(dwSector < pFat32Fs->dwFatSectorNum + pFat32Fs->dwFatBeginSector) { if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, 1, pBuffer)) //Can not read the sector from fat region. { goto __TERMINAL; } pCluster = (DWORD*)pBuffer; //Analysis the sector to find a free cluster entry. for(i = 0;i < pFat32Fs->dwBytePerSector / sizeof(DWORD);i ++) { if(0 == ((*pCluster) & 0x0FFFFFFF)) //Find one free cluster. { (*pCluster) |= 0x0FFFFFFF; //Mark the cluster to EOC,occupied. if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, 1, pBuffer)) { goto __TERMINAL; } //Write to backup FAT region. WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector + pFat32Fs->dwFatSectorNum, 1, pBuffer); //It is no matter if write to backup fat failed. bResult = TRUE; _hx_sprintf(Buffer," In GetFreeCluster,success,cluster = %d,next = %d",dwCurrCluster,*pCluster); PrintLine(Buffer); goto __TERMINAL; } pCluster ++; dwCurrCluster ++; } dwSector ++; //Travel the FAT region in sector unit one by one. } __TERMINAL: if(pBuffer) { KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0); } if(bResult) //Found one free cluster successfully,return it. { *pdwFreeCluster = dwCurrCluster; } return bResult; }
//Get the file's directory entry given it's name. // @pFat32Fs : File system extension object; // @dwStartCluster : Start cluster of the target directory; // @pFileName : File name to find,with extension; // @pShortEntry : Contain the result if successfully. // @pDirClus[OUT] : Returns the parent directory's start cluster. // @pDirOffset[OUT] : Returns the file entry's offset in parent. //Or else FALSE will be returned. BOOL GetShortEntry(__FAT32_FS* pFat32Fs, DWORD dwStartCluster, CHAR* pFileName, __FAT32_SHORTENTRY* pShortEntry, DWORD* pDirClus, DWORD* pDirOffset) { BOOL bResult = FALSE; __FAT32_SHORTENTRY* pfse = NULL; BYTE* pBuffer = NULL; DWORD dwCurrClus = 0; DWORD dwSector = 0; BYTE FileName[13]; int i; if((NULL == pFat32Fs) || (NULL == pFileName) || (pShortEntry == pfse)) { goto __TERMINAL; } //Create local buffer to contain one cluster. pBuffer = (BYTE*)KMemAlloc(pFat32Fs->SectorPerClus * pFat32Fs->dwBytePerSector,KMEM_SIZE_TYPE_ANY); if(NULL == pBuffer) { PrintLine(" In GetShortEntry: Can not allocate kernel memory."); goto __TERMINAL; } dwCurrClus = dwStartCluster; while(!IS_EOC(dwCurrClus)) //Main loop to check the root directory. { dwSector = GetClusterSector(pFat32Fs,dwCurrClus); if(0 == dwSector) //Fatal error. { PrintLine(" In GetShortEntry: Can not get cluster sector."); goto __TERMINAL; } if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, pFat32Fs->SectorPerClus, pBuffer)) //Can not read the appropriate sector(s). { PrintLine(" In GetShortEntry: Can not read sector from device."); goto __TERMINAL; } //Now check the root directory to seek the volume ID entry. pfse = (__FAT32_SHORTENTRY*)pBuffer; for(i = 0;i < pFat32Fs->SectorPerClus * 16;i ++) { if((BYTE)0xE5 == pfse->FileName[0]) //Empty entry. { pfse += 1; //Seek to the next entry. continue; } if(0 == pfse->FileName[0]) //All rest part is zero,no need to check futher. { break; } if(FILE_ATTR_LONGNAME == pfse->FileAttributes) //Long file name entry. { pfse += 1; continue; } if(FILE_ATTR_VOLUMEID & pfse->FileAttributes) //Volume label entry. { pfse += 1; continue; } if(ConvertName(pfse,FileName)) //Can not convert to regular file name string. { if(StrCmp((CHAR*)pFileName,(CHAR*)&FileName[0])) //Found. { memcpy((char*)pShortEntry,(const char*)pfse,sizeof(__FAT32_SHORTENTRY)); if(pDirClus) { *pDirClus = dwCurrClus; } if(pDirOffset) { *pDirOffset = (BYTE*)pfse - pBuffer; } bResult = TRUE; goto __TERMINAL; } } pfse += 1; } if(!GetNextCluster(pFat32Fs,&dwCurrClus)) { break; } } __TERMINAL: if(pBuffer) { KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0); } return bResult; }
//Load external modules from file system. static BOOL LoadExternalMod(LPSTR lpszModCfgFile) { CHAR FullPathName[128]; CHAR* pBuffer = NULL; CHAR* pFileBuff = NULL; CHAR* pLineBuff = NULL; HANDLE hFile = NULL; DWORD dwReadSize = 0; BOOL bResult = FALSE; __EXTERNAL_MOD_DESC modDesc; int index = 0; if(NULL == lpszModCfgFile) //Invalid file. { goto __TERMINAL; } //Form the valid path name. strcpy(FullPathName,OS_ROOT_DIR); strcat(FullPathName,lpszModCfgFile); //Try to open the file. hFile = CreateFile(FullPathName, FILE_ACCESS_READ, 0, NULL); if(NULL == hFile) { PrintLine("Can not open the module configure file."); goto __TERMINAL; } //Try to read the file. pBuffer = (CHAR*)KMemAlloc(MAX_MODCF_LEN + 1,KMEM_SIZE_TYPE_ANY); pLineBuff = (CHAR*)KMemAlloc(MAX_LINE_LENGTH + 1,KMEM_SIZE_TYPE_ANY); if((NULL == pBuffer) || (NULL == pLineBuff)) { PrintLine("In Module Manager object,LoadExternalMod: Allocate memory failed."); goto __TERMINAL; } pFileBuff = pBuffer; //Use pFileBuff to operate the memory. if(!ReadFile(hFile, MAX_MODCF_LEN, pFileBuff, &dwReadSize)) { PrintLine("Can not read MODCFG.INI file."); goto __TERMINAL; } pFileBuff[dwReadSize] = 0; //Set the end of memory block. //Now try to read each line from pBuffer and load it. while(FetchLine(pFileBuff,pLineBuff,&index)) { if(IsLineValid(pLineBuff)) { if(FetchModDesc(pLineBuff,&modDesc)) { //PrintLine(pLineBuff); LoadModule(&modDesc); //Load the module into memory. } } pFileBuff += index; //Skip the processed line. } bResult = TRUE; __TERMINAL: if(NULL != hFile) { CloseFile(hFile); } if(NULL != pBuffer) { KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0); } if(NULL != pLineBuff) { KMemFree(pLineBuff,KMEM_SIZE_TYPE_ANY,0); } return bResult; }
static void Initialize(__DEBUG_MANAGER *pThis) { __DEBUG_MANAGER *pDebugManager = pThis; __BUFFER_QUEUE *pBufferQueue = NULL; __BUFFER_QUEUE *pKRNLBufferQueue = NULL; __MUTEX *pMutexForBufferQueue = NULL; __MUTEX *pMutexForKRNLBufferQueue = NULL; int i = 0; // //****************KERNEL BUFFERQUEUE************* // Intialize the sync object // pMutexForKRNLBufferQueue = (__MUTEX*)CreateMutex(); if (!pMutexForKRNLBufferQueue)return; pDebugManager->pMutexForKRNLBufferQueue = pMutexForKRNLBufferQueue; // // Intialize the kernel BufferQueue. // pKRNLBufferQueue = (__BUFFER_QUEUE *)KMemAlloc(sizeof(__BUFFER_QUEUE),KMEM_SIZE_TYPE_ANY); if(!pKRNLBufferQueue)return; for(; i < 256; i++) { pKRNLBufferQueue->BufferQueue[i].code = 0; pKRNLBufferQueue->BufferQueue[i].format = 0; pKRNLBufferQueue->BufferQueue[i].len = 0; pKRNLBufferQueue->BufferQueue[i].time = 0; pKRNLBufferQueue->BufferQueue[i].pid = 0;// get pid pKRNLBufferQueue->BufferQueue[i].tid = 0;// get tid } // // FIXME // //pBufferQueue->head = pBufferQueue ->tail = -1; pKRNLBufferQueue->head = pBufferQueue ->tail = 0; pKRNLBufferQueue->len = 0; pKRNLBufferQueue->Enqueue = Enqueue; pKRNLBufferQueue->Dequeue = Dequeue; pDebugManager->pKRNLBufferQueue = pKRNLBufferQueue; // //**************USER BUFFERQUEUE************** // Intialize the sync object // pMutexForBufferQueue = (__MUTEX*)CreateMutex(); if (!pMutexForBufferQueue)return; pDebugManager->pMutexForBufferQueue = pMutexForBufferQueue; // // Intialize the user BufferQueue. // pBufferQueue = (__BUFFER_QUEUE *)KMemAlloc(sizeof(__BUFFER_QUEUE),KMEM_SIZE_TYPE_ANY); if(!pBufferQueue)return; for(; i < 256; i++) { pBufferQueue->BufferQueue[i].code = 0; pBufferQueue->BufferQueue[i].format = 0; pBufferQueue->BufferQueue[i].len = 0; pBufferQueue->BufferQueue[i].time = 0; pBufferQueue->BufferQueue[i].pid = 0;// get pid pBufferQueue->BufferQueue[i].tid = 0;// get tid } // // FIXME // //pBufferQueue->head = pBufferQueue ->tail = -1; pBufferQueue->head = pBufferQueue ->tail = 0; pBufferQueue->len = 0; pBufferQueue->Enqueue = Enqueue; pBufferQueue->Dequeue = Dequeue; pDebugManager->pBufferQueue = pBufferQueue; return; }
//Append one free cluster to the tail of a cluster chain. //The pdwCurrCluster contains the laster cluster of a cluster chain,if this routine //executes successfully,it will return TRUE and pdwCurrCluster contains the cluster //number value appended to chain right now.Else FALSE will be returned and the pdwCurrCluster //keep unchanged. BOOL AppendClusterToChain(__FAT32_FS* pFat32Fs,DWORD* pdwCurrCluster) { DWORD dwCurrCluster = 0; DWORD dwNextCluster = 0; DWORD dwSector = 0; DWORD dwOffset = 0; BOOL bResult = FALSE; BYTE* pBuffer = NULL; DWORD dwEndCluster = 0; if((NULL == pFat32Fs) || (NULL == pdwCurrCluster)) { goto __TERMINAL; } dwCurrCluster = *pdwCurrCluster; if((2 > dwCurrCluster) || IS_EOC(dwCurrCluster)) { goto __TERMINAL; } dwSector = dwCurrCluster / 128; if(dwSector > pFat32Fs->dwFatSectorNum) //Exceed the FAT size. { goto __TERMINAL; } dwSector += pFat32Fs->dwFatBeginSector; //Now dwSector is the physical sector number of dwCurrCluster in fat. dwOffset = (dwCurrCluster - (dwCurrCluster / 128) * 128) * sizeof(DWORD); //Get sector offset. pBuffer = (BYTE*)KMemAlloc(pFat32Fs->dwBytePerSector,KMEM_SIZE_TYPE_ANY); if(NULL == pBuffer) { goto __TERMINAL; } //Try to get a free cluster. if(!GetFreeCluster(pFat32Fs,0,&dwNextCluster)) { goto __TERMINAL; } //The following operation must behind GetFreeCluster routine above,because //GetFreeCluster routine will modify the content of FAT,and this change must //be taken before the following read. //One complicated problem has been caused by this reason. if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, 1, pBuffer)) { goto __TERMINAL; } //Save the next cluster to chain. *(DWORD*)(pBuffer + dwOffset) &= 0xF0000000; //Keep the leading 4 bits. *(DWORD*)(pBuffer + dwOffset) += (dwNextCluster & 0x0FFFFFFF); if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, 1, pBuffer)) { ReleaseCluster(pFat32Fs,dwNextCluster); //Release this cluster. goto __TERMINAL; } dwEndCluster = *(DWORD*)(pBuffer + dwOffset); if(!GetNextCluster(pFat32Fs,&dwEndCluster)) { PrintLine(" In AppendClusterToChain: Can not get next cluster."); } bResult = TRUE; //Anything is in place. __TERMINAL: if(pBuffer) //Should release it. { KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0); } if(bResult) { *pdwCurrCluster = (dwNextCluster & 0x0FFFFFFF); } return bResult; }
// //The lpStartAddr is the start address of linear memory space,and the lpEndAddr is the //end address of linear address space. //For example: // // ------------- // | | <----- lpStartAddr // | | // | | // ... ... // | | // | | <----- lpEndAddr // ------------- // // If the lpStartAddr is 0x00100000,and the memory's size is 4M,then,the lpEndAddr must be // 0x004FFFFF,not 0x00500000. // // If the lpStartAddr and the lpEndAddr's value does not align with 4K boundary,then the // routine will round them to 4k boundary. // static BOOL PageFrameMgrInit(__COMMON_OBJECT* lpThis, LPVOID lpStartAddr, LPVOID lpEndAddr) { __PAGE_FRAME_MANAGER* lpFrameManager = NULL; BOOL bResult = FALSE; LPVOID lpStartAddress = NULL; LPVOID lpEndAddress = NULL; DWORD dwPageNum = 0; __PAGE_FRAME* lpPageFrameArray = NULL; DWORD i = 0; DWORD j = 0; DWORD k = 0; DWORD dwTotalMemLen = 0; DWORD dwIndBase = 0; BUG_ON(NULL == lpThis); lpFrameManager = (__PAGE_FRAME_MANAGER*)lpThis; lpStartAddress = ALIGN_DOWN_TO_PAGE(lpStartAddr); lpEndAddress = (LPVOID)((DWORD)lpEndAddr + 1); //Adjust the end address. lpEndAddress = ALIGN_UP_TO_PAGE(lpEndAddress); if ((DWORD)((DWORD)lpEndAddress - (DWORD)lpStartAddress) < PAGE_FRAME_SIZE) { goto __TERMINAL; } dwPageNum = ((DWORD)lpEndAddress - (DWORD)lpStartAddress) / PAGE_FRAME_SIZE; lpPageFrameArray = (__PAGE_FRAME*)KMemAlloc(dwPageNum * sizeof(__PAGE_FRAME), KMEM_SIZE_TYPE_ANY); if (NULL == lpPageFrameArray) { goto __TERMINAL; } // //Initializes the members of page frame manager. // lpFrameManager->lpStartAddress = lpStartAddress; lpFrameManager->dwTotalFrameNum = dwPageNum; lpFrameManager->dwFreeFrameNum = dwPageNum; lpFrameManager->lpPageFrameArray = lpPageFrameArray; #if defined(__CFG_SYS_SMP) __INIT_SPIN_LOCK(lpFrameManager->spin_lock, "frmmgr"); #endif //--------------- ** debug ** -------------------------- //printf("Initialize: Total Page Frame number : %d\r\n",dwPageNum); //printf("Initialize: Start Address at : %d\r\n",(DWORD)lpStartAddress); //printf("Initialize: Page Frame Array base : %d\r\n",(DWORD)lpPageFrameArray); /* Initialize all bitmap to NULL. */ for(i = 0;i < PAGE_FRAME_BLOCK_NUM;i ++) { lpFrameManager->FrameBlockArray[i].lpdwBitmap = NULL; lpFrameManager->FrameBlockArray[i].lpNextBlock = NULL; lpFrameManager->FrameBlockArray[i].lpPrevBlock = NULL; } /* Initializes the bitmap of page frame block. */ for(i = 0;i < PAGE_FRAME_BLOCK_NUM;i ++) { lpFrameManager->FrameBlockArray[i].lpdwBitmap = (DWORD*)KMemAlloc((dwPageNum / sizeof(DWORD) + 1)*sizeof(DWORD),KMEM_SIZE_TYPE_ANY); if (NULL == lpFrameManager->FrameBlockArray[i].lpdwBitmap) { goto __TERMINAL; } for (j = 0; j < (dwPageNum / sizeof(DWORD) + 1) * sizeof(DWORD); j++) { ((UCHAR*)lpFrameManager->FrameBlockArray[i].lpdwBitmap)[j] = 0; } if (0 == dwPageNum) { break; } dwPageNum /= 2; } // //The following code splits the whole physical memory into page frame blocks,and insert //them into page frame block list of Page Frame Manager. // dwTotalMemLen = lpFrameManager->dwTotalFrameNum * PAGE_FRAME_SIZE; dwIndBase = 0; for(i = PAGE_FRAME_BLOCK_NUM;i > 0;i --) { j = dwTotalMemLen / FrameBlockSize[i - 1]; k = FrameBlockSize[i - 1] / PAGE_FRAME_SIZE; while(j) //Insert the block into list. { j --; if(lpFrameManager->FrameBlockArray[i - 1].lpNextBlock) { lpFrameManager->FrameBlockArray[i - 1].lpNextBlock->lpPrevFrame = &(lpFrameManager->lpPageFrameArray[dwIndBase + j * k]); } lpFrameManager->lpPageFrameArray[dwIndBase + j * k].lpNextFrame = lpFrameManager->FrameBlockArray[i - 1].lpNextBlock; lpFrameManager->lpPageFrameArray[dwIndBase + j * k].lpPrevFrame = NULL; lpFrameManager->FrameBlockArray[i - 1].lpNextBlock = &(lpFrameManager->lpPageFrameArray[dwIndBase + j * k]); /* Set the appropriate bitmap bit,to indicate the block exists. */ SetBitmapBit(lpFrameManager->FrameBlockArray[i - 1].lpdwBitmap, dwIndBase / k + j); } j = dwTotalMemLen / FrameBlockSize[i - 1]; dwIndBase += j * k; dwTotalMemLen -= j * FrameBlockSize[i - 1]; } bResult = TRUE; //Set the successful initialization flag. __TERMINAL: if(!bResult) //Failed to initialize the object. { if(lpFrameManager->lpPageFrameArray) KMemFree((LPVOID)lpFrameManager->lpPageFrameArray,KMEM_SIZE_TYPE_ANY,0); for(i = 0;i < PAGE_FRAME_BLOCK_NUM;i ++) { if(lpFrameManager->FrameBlockArray[i].lpdwBitmap) KMemFree((void*)lpFrameManager->FrameBlockArray[i].lpdwBitmap, KMEM_SIZE_TYPE_ANY,0); } } return bResult; }
// //The following routine is used to add one PCI device(physical device) into a PCI //bus. //It first create a physical device and a PCI information structure,then initializes //them by reading data from configure space. // static VOID PciAddDevice(DWORD dwConfigReg,__SYSTEM_BUS* lpSysBus) { __PCI_DEVICE_INFO* lpDevInfo = NULL; __PHYSICAL_DEVICE* lpPhyDev = NULL; DWORD dwFlags = 0; BOOL bResult = FALSE; //DWORD dwLoop = 0; DWORD dwTmp = 0; if((0 == dwConfigReg) || (NULL == lpSysBus)) //Invalid parameters. return; lpPhyDev = (__PHYSICAL_DEVICE*)KMemAlloc(sizeof(__PHYSICAL_DEVICE), KMEM_SIZE_TYPE_ANY); //Create physical device. if(NULL == lpPhyDev) goto __TERMINAL; lpDevInfo = (__PCI_DEVICE_INFO*)KMemAlloc(sizeof(__PCI_DEVICE_INFO), KMEM_SIZE_TYPE_ANY); if(NULL == lpDevInfo) //Can not allocate information structure. goto __TERMINAL; lpDevInfo->DeviceNum = (dwConfigReg >> 11) & 0x0000001F; //Get device number. lpDevInfo->FunctionNum = (dwConfigReg >> 8) & 0x00000007; //Get function number. lpPhyDev->lpPrivateInfo = (LPVOID)lpDevInfo; //Link device information to physical device. //Save device number to physical device object. lpPhyDev->dwNumber = dwConfigReg & 0x0000FF00; lpPhyDev->dwNumber >>= 8; // //The following code initializes identifier member of physical device. // dwConfigReg &= 0xFFFFFF00; //Clear offset part. dwConfigReg += PCI_CONFIG_OFFSET_VENDOR; __outd(CONFIG_REGISTER,dwConfigReg); dwTmp = __ind(DATA_REGISTER); //Read vendor ID and device ID. lpPhyDev->DevId.dwBusType = BUS_TYPE_PCI; lpPhyDev->DevId.Bus_ID.PCI_Identifier.ucMask = PCI_IDENTIFIER_MASK_ALL; lpPhyDev->DevId.Bus_ID.PCI_Identifier.wVendor = (WORD)dwTmp; lpPhyDev->DevId.Bus_ID.PCI_Identifier.wDevice = (WORD)(dwTmp >> 16); dwConfigReg &= 0xFFFFFF00; dwConfigReg += PCI_CONFIG_OFFSET_REVISION; //Get revision ID and class code. __outd(CONFIG_REGISTER,dwConfigReg); dwTmp = __ind(DATA_REGISTER); lpPhyDev->DevId.Bus_ID.PCI_Identifier.dwClass = dwTmp; lpDevInfo->dwClassCode = dwTmp; //Save to information struct also. dwConfigReg &= 0xFFFFFF00; dwConfigReg += PCI_CONFIG_OFFSET_CACHELINESZ; //Get header type. __outd(CONFIG_REGISTER,dwConfigReg); dwTmp = __ind(DATA_REGISTER); lpPhyDev->DevId.Bus_ID.PCI_Identifier.ucHdrType = (UCHAR)(dwTmp >> 16); //Get header type. // //The following code initializes the resource information required by device. // switch((dwTmp >> 16) & 0x7F) { case 0: //Normal PCI device. lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_NORMAL; dwConfigReg &= 0xFFFFFF00; PciFillDevResources(dwConfigReg,lpPhyDev); bResult = TRUE; break; case 1: //PCI-PCI bridge. lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_BRIDGE; dwConfigReg &= 0xFFFFFF00; PciFillBridgeResources(dwConfigReg,lpPhyDev); bResult = TRUE; break; case 2: //CardBus-PCI bridge. lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_CARDBUS; bResult = TRUE; break; default: //Not supported yet. lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_UNSUPPORTED; bResult = TRUE; break; } //Set up physical device's configuration reading/writting routine. lpPhyDev->ReadDeviceConfig = PciReadDeviceConfig; lpPhyDev->WriteDeviceConfig = PciWriteDeviceConfig; // //Now,we have finished to initialize resource information,so we insert the physical device //object into system bus. // lpPhyDev->lpHomeBus = lpSysBus; __ENTER_CRITICAL_SECTION(NULL,dwFlags); lpPhyDev->lpNext = lpSysBus->lpDevListHdr; lpSysBus->lpDevListHdr = lpPhyDev; __LEAVE_CRITICAL_SECTION(NULL,dwFlags); __TERMINAL: if(!bResult) { if(lpPhyDev) //Release memory. KMemFree((LPVOID)lpPhyDev,KMEM_SIZE_TYPE_ANY,0); if(lpDevInfo) KMemFree((LPVOID)lpDevInfo,KMEM_SIZE_TYPE_ANY,0); } return; }
// //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; }
//The following function form the command parameter object link from the command //line string. // __CMD_PARA_OBJ* FormParameterObj(LPSTR pszCmd) { __CMD_PARA_OBJ* pObjBuffer = NULL; //Local variables. __CMD_PARA_OBJ* pBasePtr = NULL; __CMD_PARA_OBJ* pTmpObj = NULL; DWORD dwCounter = 0x0000; DWORD index = 0x0000; if(NULL == pszCmd) //Parameter check. return NULL; pObjBuffer = (__CMD_PARA_OBJ*)KMemAlloc(sizeof(__CMD_PARA_OBJ),KMEM_SIZE_TYPE_ANY); if(NULL == pObjBuffer) { goto __TERMINAL; } pBasePtr = pObjBuffer; memzero(pBasePtr,sizeof(__CMD_PARA_OBJ)); while(*pszCmd) { if(' ' == *pszCmd) { pszCmd ++; continue; } //Filter the space. if(('-' == *pszCmd) || ('/' == *pszCmd)) { pszCmd ++; pObjBuffer->byFunctionLabel = *pszCmd; pszCmd ++; //Skip the function label byte. continue; } else { /*while((' ' != *pszCmd) && *pszCmd) //To find the first parameter. { pszCmd ++; } if(!*pszCmd) break; while(' ' == *pszCmd) //Filter the space. pszCmd ++; if(!*pszCmd) break;*/ index = 0x0000; while(('-' != *pszCmd) && ('/' != *pszCmd) && *pszCmd) { while((' ' != *pszCmd) && (*pszCmd) && (dwCounter <= CMD_PARAMETER_LEN)) { pObjBuffer->Parameter[index][dwCounter] = *pszCmd; pszCmd ++; dwCounter ++; } pObjBuffer->Parameter[index][dwCounter] = 0x00; //Set the terminal flag. index ++; //Ready to copy the next parameter to parameter object. dwCounter = 0; if(!*pszCmd) break; while(' ' != *pszCmd) pszCmd ++; //Skip the no space characters if the parameter's length //is longer than the const CMD_PARAMETER_LEN. while(' ' == *pszCmd) pszCmd ++; //Skip the space character. } pTmpObj = pObjBuffer; //Update the current parameter object. pObjBuffer = (__CMD_PARA_OBJ*)NextParaAddr(pTmpObj,index); pTmpObj->byParameterNum = (BYTE)(index); if(!*pszCmd) break; pTmpObj->pNext = pObjBuffer; } } __TERMINAL: return pBasePtr; }
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; }
/* * Add one PCI device(physical device) into a PCI * bus. * It first create a physical device and a PCI information structure,then initializes * them by reading data from configure space. */ static VOID PciAddDevice(DWORD dwConfigReg,__SYSTEM_BUS* lpSysBus) { __PCI_DEVICE_INFO* lpDevInfo = NULL; __PHYSICAL_DEVICE* lpPhyDev = NULL; BOOL bResult = FALSE; DWORD dwTmp = 0; /* Basic checking. */ if ((0 == dwConfigReg) || (NULL == lpSysBus)) { return; } /* Only available in process of system initialization. */ BUG_ON(!IN_SYSINITIALIZATION()); /* Create physical device. */ lpPhyDev = (__PHYSICAL_DEVICE*)KMemAlloc(sizeof(__PHYSICAL_DEVICE), KMEM_SIZE_TYPE_ANY); if (NULL == lpPhyDev) { goto __TERMINAL; } memset(lpPhyDev, 0, sizeof(__PHYSICAL_DEVICE)); /* Create PCI device information structure. */ lpDevInfo = (__PCI_DEVICE_INFO*)KMemAlloc(sizeof(__PCI_DEVICE_INFO), KMEM_SIZE_TYPE_ANY); if (NULL == lpDevInfo) { goto __TERMINAL; } memset(lpDevInfo, 0, sizeof(__PCI_DEVICE_INFO)); lpDevInfo->DeviceNum = (dwConfigReg >> 11) & 0x0000001F; //Get device number. lpDevInfo->FunctionNum = (dwConfigReg >> 8) & 0x00000007; //Get function number. lpPhyDev->lpPrivateInfo = (LPVOID)lpDevInfo; //Link device information to physical device. //Save device number to physical device object. lpPhyDev->dwNumber = dwConfigReg & 0x0000FF00; lpPhyDev->dwNumber >>= 8; /* Initializes identifier member of physical device. */ dwConfigReg &= 0xFFFFFF00; //Clear offset part. dwConfigReg += PCI_CONFIG_OFFSET_VENDOR; __outd(CONFIG_REGISTER,dwConfigReg); dwTmp = __ind(DATA_REGISTER); //Read vendor ID and device ID. lpPhyDev->DevId.dwBusType = BUS_TYPE_PCI; lpPhyDev->DevId.Bus_ID.PCI_Identifier.ucMask = PCI_IDENTIFIER_MASK_ALL; lpPhyDev->DevId.Bus_ID.PCI_Identifier.wVendor = (WORD)dwTmp; lpPhyDev->DevId.Bus_ID.PCI_Identifier.wDevice = (WORD)(dwTmp >> 16); dwConfigReg &= 0xFFFFFF00; dwConfigReg += PCI_CONFIG_OFFSET_REVISION; //Get revision ID and class code. __outd(CONFIG_REGISTER,dwConfigReg); dwTmp = __ind(DATA_REGISTER); lpPhyDev->DevId.Bus_ID.PCI_Identifier.dwClass = dwTmp; /* Save to information struct also. */ lpDevInfo->dwClassCode = dwTmp; dwConfigReg &= 0xFFFFFF00; /* Get header type. */ dwConfigReg += PCI_CONFIG_OFFSET_CACHELINESZ; __outd(CONFIG_REGISTER,dwConfigReg); dwTmp = __ind(DATA_REGISTER); /* Get header type. */ lpPhyDev->DevId.Bus_ID.PCI_Identifier.ucHdrType = (UCHAR)(dwTmp >> 16); /* Initializes the resource information required by device. */ switch((dwTmp >> 16) & 0x7F) { case 0: /* Normal PCI device. */ lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_NORMAL; dwConfigReg &= 0xFFFFFF00; PciFillDevResources(dwConfigReg,lpPhyDev); bResult = TRUE; break; case 1: /* PCI-PCI bridge. */ lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_BRIDGE; dwConfigReg &= 0xFFFFFF00; PciFillBridgeResources(dwConfigReg,lpPhyDev); bResult = TRUE; break; case 2: /* CardBus-PCI bridge. */ lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_CARDBUS; bResult = TRUE; break; default: /* Not supported yet. */ lpDevInfo->dwDeviceType = PCI_DEVICE_TYPE_UNSUPPORTED; bResult = TRUE; break; } //Set up physical device's configuration reading/writting routine. lpPhyDev->ReadDeviceConfig = PciReadDeviceConfig; lpPhyDev->WriteDeviceConfig = PciWriteDeviceConfig; /* * Now,we have finished to initialize resource information,just insert the physical device * object into system bus. */ lpPhyDev->lpHomeBus = lpSysBus; bResult = DeviceManager.AppendDevice(&DeviceManager, lpPhyDev); __TERMINAL: if(!bResult) { if (lpPhyDev) { KMemFree((LPVOID)lpPhyDev, KMEM_SIZE_TYPE_ANY, 0); } if (lpDevInfo) { KMemFree((LPVOID)lpDevInfo, KMEM_SIZE_TYPE_ANY, 0); } } return; }
//Initializes one directory,i.e,write dot and dotdot directories into one directory newly created. // @dwParentCluster : The start cluster number of target directory's parent directory; // @dwDirCluster : The start cluster number of target directory. BOOL InitDirectory(__FAT32_FS* pFat32Fs,DWORD dwParentCluster,DWORD dwDirCluster) { BYTE* pBuffer = NULL; //Temprory buffer used to contain first cluster. __FAT32_SHORTENTRY* pfse = NULL; BOOL bResult = FALSE; DWORD dwDirSector = 0; CHAR Buffer[128]; if((NULL == pFat32Fs) || (dwParentCluster < 2) || (dwDirCluster < 2) || IS_EOC(dwParentCluster) || IS_EOC(dwDirCluster)) { _hx_sprintf(Buffer," In InitDirectory: parent clus = %d,dir clus = %d", dwParentCluster, dwDirCluster); PrintLine(Buffer); PrintLine(" In InitDirectory: Condition 0"); goto __TERMINAL; } //Allocate temporary buffer. pBuffer = (BYTE*)KMemAlloc(pFat32Fs->dwClusterSize, KMEM_SIZE_TYPE_ANY); if(NULL == pBuffer) { PrintLine(" In InitDirectory: Condition 1"); goto __TERMINAL; } dwDirSector = GetClusterSector(pFat32Fs,dwDirCluster); //Get the start cluster number of target dir. if(IS_EOC(dwDirSector)) { PrintLine(" In InitDirectory: Condition 2"); goto __TERMINAL; } //Clear cluster's content to zero. memzero(pBuffer,pFat32Fs->dwClusterSize); pfse = (__FAT32_SHORTENTRY*)pBuffer; InitShortEntry(pfse,".",dwDirCluster,0,FILE_ATTR_DIRECTORY); //Create the dot directory. /*pfse->CreateDate = 0; pfse->CreateTime = 0; pfse->CreateTimeTenth = 0; pfse->dwFileSize = 0; pfse->FileAttributes = FILE_ATTR_DIRECTORY; pfse->FileName[0] = '.'; pfse->LastAccessDate = 0; pfse->wFirstClusHi = (WORD)(dwDirCluster >> 16); pfse->wFirstClusLow = (WORD)dwDirCluster; pfse->WriteDate = 0; pfse->WriteTime = 0;*/ pfse ++; //Create the dotdot directory. InitShortEntry(pfse,"..",dwDirCluster,0,FILE_ATTR_DIRECTORY); /*pfse->CreateDate = 0; pfse->CreateTime = 0; pfse->CreateTimeTenth = 0; pfse->dwFileSize = 0; pfse->FileAttributes = FILE_ATTR_DIRECTORY; pfse->FileName[0] = '.'; pfse->FileName[1] = '.'; pfse->LastAccessDate = 0; pfse->wFirstClusHi = (WORD)(dwParentCluster >> 16); pfse->wFirstClusLow = (WORD)dwParentCluster; pfse->WriteDate = 0; pfse->WriteTime = 0;*/ pfse ++; //Write the cluster into directory. if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwDirSector, pFat32Fs->SectorPerClus, pBuffer)) { PrintLine(" In InitDirectory: Condition 3"); goto __TERMINAL; } bResult = TRUE; __TERMINAL: if(pBuffer) { KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0); } return bResult; }
static DWORD GetMail(__COMMON_OBJECT* lpThis,LPVOID* llpMsg,DWORD dwTimeOut) { __MAILBOX* lpMailBox = NULL; __KERNEL_THREAD_OBJECT* lpKernelThread = NULL; DWORD dwLoop = 0L; __TIMER_HANDLER_PARAM* lpTimerHandlerParam = NULL; __TIMER_OBJECT* lpTimerObject = NULL; if((NULL == lpThis) || (NULL == llpMsg)) //Parameters check. return MAILBOX_FAILED; lpMailBox = (__MAILBOX*)lpThis; ENTER_CRITICAL_SECTION(); if(lpMailBox->dwMsgNum > 0) //There at least a message in the mail box. { for(dwLoop = 0;dwLoop < MAILBOX_MSG_NUM;dwLoop ++) { if(lpMailBox->MsgArray[dwLoop]) { *llpMsg = lpMailBox->MsgArray[dwLoop]; //Get the message. lpMailBox->MsgArray[dwLoop] = NULL; lpMailBox->dwMsgNum --; //Decrement the message number. LEAVE_CRITICAL_SECTION(); return MAILBOX_SUCCESS; } } LEAVE_CRITICAL_SECTION(); //The following instructions can never be reached normallly. return MAILBOX_FAILED; } else //There is not any message in the mailbox. { lpKernelThread = KernelThreadManager.lpCurrentKernelThread; lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED; //Block the current thread. LEAVE_CRITICAL_SECTION(); if(dwTimeOut) //Should set a timer to process the timeout operation. { lpTimerHandlerParam = (__TIMER_HANDLER_PARAM*)KMemAlloc( sizeof(__TIMER_HANDLER_PARAM), KMEM_SIZE_TYPE_ANY); //Allocate a memory block,this block is released by timer //handler. if(NULL == lpTimerHandlerParam) //Can not allocate memory. { lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING; return MAILBOX_FAILED; } lpTimerHandlerParam->lpMailBox = lpMailBox; lpTimerHandlerParam->lpKernelThread = lpKernelThread; lpTimerHandlerParam->bCanceled = FALSE; lpTimerHandlerParam->llpHandlerParam = (LPVOID*)&lpTimerHandlerParam; lpTimerHandlerParam->dwWakenupReason = WAKEN_UP_REASON_HAVE_MESSAGE; lpTimerObject = (__TIMER_OBJECT*)System.SetTimer((__COMMON_OBJECT*)&System, lpKernelThread, MAILBOX_TIMEOUT_TIMER_ID, dwTimeOut, TimerHandler, lpTimerHandlerParam, TIMER_FLAGS_ONCE); //Set a timer to process the timeout. //CAUTION!!! : Currently,we do not process the potential error. } lpMailBox->lpWaitingQueue->InsertIntoQueue( (__COMMON_OBJECT*)lpMailBox->lpWaitingQueue, (__COMMON_OBJECT*)lpKernelThread, 0L); //Insert into mailbox's waiting queue. KernelThreadManager.ScheduleFromProc(&lpKernelThread->KernelThreadContext); //Re-schedule. } // //The following code is executed when the kernel thread is waken up. //Two cases exist: // 1. One kernel thread have sent a message to the mailbox,and wake up the current kernel // thread; // 2. The waiting is canceled by a timer,in case of timeout not equal zero. //In the first case,the kernel thread get a message from mailbox,and check if a timer //has been set,if set,then cancel the timer by set bCanceled to TRUE. //In the second case,the kernel thread only returns a MAILBOX_TIME out value. // ENTER_CRITICAL_SECTION(); if(dwTimeOut == 0) //Have not set a timer. { for(dwLoop = 0;dwLoop < MAILBOX_MSG_NUM;dwLoop ++) { if(NULL != lpMailBox->MsgArray[dwLoop]) { *llpMsg = lpMailBox->MsgArray[dwLoop]; lpMailBox->MsgArray[dwLoop] = NULL; lpMailBox->dwMsgNum --; } } LEAVE_CRITICAL_SECTION(); return MAILBOX_SUCCESS; } // //The following code is used to deal with timeout process. // switch(lpTimerHandlerParam->dwWakenupReason) { case WAKEN_UP_REASON_TIMEOUT: KMemFree((LPVOID)lpTimerHandlerParam,KMEM_SIZE_TYPE_ANY,0L); LEAVE_CRITICAL_SECTION(); return MAILBOX_TIMEOUT; case WAKEN_UP_REASON_HAVE_MESSAGE: for(dwLoop = 0;dwLoop < MAILBOX_MSG_NUM;dwLoop ++) { if(NULL != lpMailBox->MsgArray[dwLoop]) { *llpMsg = lpMailBox->MsgArray[dwLoop]; lpMailBox->MsgArray[dwLoop] = NULL; lpMailBox->dwMsgNum --; if(dwTimeOut) //Should cancel the timer. { System.CancelTimer((__COMMON_OBJECT*)&System, (__COMMON_OBJECT*)lpTimerObject); KMemFree((LPVOID)lpTimerHandlerParam,KMEM_SIZE_TYPE_ANY,0L); } } } LEAVE_CRITICAL_SECTION(); return MAILBOX_SUCCESS; default: KMemFree((LPVOID)lpTimerHandlerParam,KMEM_SIZE_TYPE_ANY,0L); LEAVE_CRITICAL_SECTION(); return MAILBOX_FAILED; } //The following code will never be reached. return MAILBOX_FAILED; }
//Find one empty short directory entry in a cluster chain start from dwStartCluster, //and save the short entry pointed by pfse into this entry.If can not find a free one //in the whole cluster chain,then append a free cluster in the chain and save it. BOOL CreateDirEntry(__FAT32_FS* pFat32Fs,DWORD dwStartCluster,__FAT32_SHORTENTRY* pDirEntry) { __FAT32_SHORTENTRY DirEntry; __FAT32_SHORTENTRY* pfse = NULL; DWORD dwSector = 0; DWORD dwCurrCluster = 0; DWORD dwNextCluster = 0; BYTE* pBuffer = NULL; CHAR DirName[13] = {0}; DWORD i; BOOL bFind = FALSE; BOOL bResult = FALSE; if((NULL == pFat32Fs) || (dwStartCluster < 2) || IS_EOC(dwStartCluster) || (NULL == pDirEntry)) { PrintLine(" In CreateDirEntry,Condition 0"); goto __TERMINAL; } if(!ConvertName(pDirEntry,(BYTE*)&DirName[0])) { PrintLine(" In CreateDirEntry,Condition 1"); goto __TERMINAL; } //Check if the directory to be created has already in directory. if(GetShortEntry(pFat32Fs,dwStartCluster,DirName,&DirEntry,NULL,NULL)) //Directory already exists. { PrintLine(" In CreateDirEntry: The specified directory already exist."); goto __TERMINAL; } pBuffer = (BYTE*)KMemAlloc(pFat32Fs->dwClusterSize,KMEM_SIZE_TYPE_ANY); if(NULL == pBuffer) { PrintLine(" In CreateDirEntry,can not allocate memory for temporary buffer."); goto __TERMINAL; } //Try to find a free directory entry in the given directory,if can not find,then //allocate a free cluster,append it to the given directory. dwNextCluster = dwStartCluster; while(!IS_EOC(dwNextCluster)) { dwCurrCluster = dwNextCluster; dwSector = GetClusterSector(pFat32Fs,dwCurrCluster); if(0 == dwSector) { PrintLine(" In CreateDirEntry,Condition 2"); goto __TERMINAL; } if(!ReadDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, pFat32Fs->SectorPerClus, pBuffer)) { PrintLine(" In CreateDirEntry,Condition 3"); goto __TERMINAL; } //Search this cluster from begin. pfse = (__FAT32_SHORTENTRY*)pBuffer; for(i = 0;i < pFat32Fs->dwClusterSize / sizeof(__FAT32_SHORTENTRY);i++) { if((0 == pfse->FileName[0]) || ((BYTE)0xE5 == pfse->FileName[0])) //Find a free slot. { bFind = TRUE; break; } pfse ++; } if(bFind) //Find a free directory entry,no need to check further. { break; } //Can not find a free directory slot,try to search next cluster. if(!GetNextCluster(pFat32Fs,&dwNextCluster)) { PrintLine(" In CreateDirEntry,Condition 4"); goto __TERMINAL; } } if(bFind) //Has found a free directory slot. { memcpy((char*)pfse,(const char*)pDirEntry,sizeof(__FAT32_SHORTENTRY)); if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, pFat32Fs->SectorPerClus, pBuffer)) { PrintLine(" In CreateDirEntry,Condition 5"); goto __TERMINAL; } } else //Can not find a free slot,allocate a new cluster for parent directory. { if(!AppendClusterToChain(pFat32Fs,&dwCurrCluster)) { PrintLine(" In CreateDirEntry: Can not append a free cluster to this dir."); goto __TERMINAL; } memzero(pBuffer,pFat32Fs->dwClusterSize); memcpy((char*)pBuffer,(const char*)pDirEntry,sizeof(__FAT32_SHORTENTRY)); dwSector = GetClusterSector(pFat32Fs,dwCurrCluster); if(!WriteDeviceSector((__COMMON_OBJECT*)pFat32Fs->pPartition, dwSector, pFat32Fs->SectorPerClus, pBuffer)) { PrintLine(" In CreateDirEntry,Condition 6"); goto __TERMINAL; } } /* _hx_sprintf(pBuffer,"In CreateDirEntry: dwSector = %d,dwCurrCluster = %d,offset = %d", dwSector, dwCurrCluster, (BYTE*)pfse - pBuffer); PrintLine(pBuffer);*/ bResult = TRUE; __TERMINAL: if(pBuffer) { KMemFree(pBuffer,KMEM_SIZE_TYPE_ANY,0); } return bResult; }
//Implementation of CheckPartiton routine.This routine will be called by //IOManager when a storage partition object is created in system.The NTFS //file system driver code should detect if the partition is formated as //NTFS file system,and should create a NTFS device object if so,RegisterFileSystem //also should be called under this scenario to tell system that a NTFS partition //existing. static BOOL CheckPartition(__COMMON_OBJECT* pThis,__COMMON_OBJECT* pPartitionObject) { __DEVICE_OBJECT* pNtfsDeviceObject = NULL; //NTFS device object. __DEVICE_OBJECT* pPartitionDevice = (__DEVICE_OBJECT*)pPartitionObject; __NTFS_FILE_SYSTEM* pFileSystem = NULL; //NTFS file system object. CHAR DevName[64]; //NTFS device's name. int nIndex = 0; //Used to locate device name number. static int nNameIndex = 0; //Start name index number. BOOL bResult = FALSE; BYTE* pSector0 = NULL; //Buffer to contain sector of this part. if(NULL == pPartitionDevice) { goto __TERMINAL; } //Allocate buffer. pSector0 = (BYTE*)KMemAlloc(SECTOR_SIZE,KMEM_SIZE_TYPE_ANY); if(NULL == pSector0) { PrintLine("NTFS CheckPartition : Can not allocate memory for reading sector0."); goto __TERMINAL; } //Read the first sector of partition object now. if(!NtfsReadDeviceSector(pPartitionObject, 0, 1, pSector0)) { PrintLine("NTFS CheckPartition : Can not read first sector from partition object."); goto __TERMINAL; } //OK,try to create NTFS object. pFileSystem = CreateNtfsFileSystem(pPartitionObject,pSector0); if(NULL == pFileSystem) { PrintLine("NTFS CheckPartition : Can not create file system object."); goto __TERMINAL; } //NTFS file system object created successfully and we should create the corresponding //device object. strcpy(DevName,NTFS_DEVICE_NAME_BASE); nIndex = strlen(DevName); DevName[nIndex - 1] += nNameIndex; nNameIndex ++; pNtfsDeviceObject = IOManager.CreateDevice( (__COMMON_OBJECT*)&IOManager, DevName, DEVICE_TYPE_NTFS, DEVICE_BLOCK_SIZE_INVALID, DEVICE_BLOCK_SIZE_INVALID, DEVICE_BLOCK_SIZE_INVALID, (LPVOID)pFileSystem, ((__DEVICE_OBJECT*)pThis)->lpDriverObject); if(NULL == pNtfsDeviceObject) { PrintLine("NTFS CheckPartition : Can not create device object."); goto __TERMINAL; } //Now Add the file system object to system. if(!IOManager.AddFileSystem( (__COMMON_OBJECT*)&IOManager, (__COMMON_OBJECT*)pNtfsDeviceObject, 0, pFileSystem->volLabel)) { goto __TERMINAL; } //Everything is OK. bResult = TRUE; __TERMINAL: if(NULL != pSector0) { KMemFree(pSector0,KMEM_SIZE_TYPE_ANY,0); } if(!bResult) { if(NULL != pNtfsDeviceObject) { IOManager.DestroyDevice((__COMMON_OBJECT*)&IOManager, pNtfsDeviceObject); } if(pFileSystem) { DestroyNtfsFileSystem(pFileSystem); } } return bResult; }
// //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; }