static void Log(__DEBUG_MANAGER *pThis, char *tag, char *msg) { __DEBUG_MANAGER *pDebugManager = pThis; __LOG_MESSAGE *pMsg = NULL; __KERNEL_THREAD_OBJECT *lpCurrentThread = NULL; int dwFlags = 0; int Result = -1; 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->pMutexForBufferQueue->WaitForThisObject((__COMMON_OBJECT*)DebugManager.pMutexForBufferQueue); if (Result == OBJECT_WAIT_RESOURCE) { pDebugManager->pBufferQueue->Enqueue( pDebugManager->pBufferQueue, pMsg); pDebugManager->pMutexForBufferQueue->ReleaseMutex((__COMMON_OBJECT*)DebugManager.pMutexForBufferQueue); } KMemFree(pMsg, KMEM_SIZE_TYPE_ANY, 0); return; }
// //Releases the parameter object created by FormParameterObj routine. // VOID ReleaseParameterObj(__CMD_PARA_OBJ* lpParamObj) { __CMD_PARA_OBJ* pNext = NULL; if(NULL == lpParamObj) //Parameter check. { return; } do{ pNext = lpParamObj->pNext; KMemFree((LPVOID)lpParamObj,KMEM_SIZE_TYPE_ANY,0); lpParamObj = pNext; }while(pNext); }
int pthread_cond_destroy (pthread_cond_t * cond) { __CONDITION* pCond = NULL; if(NULL == cond) { return EINVAL; } if(NULL == (*cond)->cond) { return EINVAL; } DestroyCondition((HANDLE)((*cond)->cond)); KMemFree((*cond),KMEM_SIZE_TYPE_ANY,0); return S_OK; }
// //The following function terminal a kernal thread roughly. // VOID TerminalKThread(DWORD dwKThreadID) { struct __KTHREAD_CONTROL_BLOCK* pControlBlock = NULL; DWORD dwStackSize = 0; if((dwKThreadID < 1) || (dwKThreadID > MAX_KTHREAD_NUM)) //Parameter check. return; dwKThreadID --; //Make sure the dwKThreadID is the index //to allocate the system array. g_bKThreadQueueStatus[dwKThreadID] = 0; //Free the control block slot. pControlBlock = g_pKThreadQueue[dwKThreadID]; if(NULL != pControlBlock) { dwStackSize = pControlBlock->dwStackSize; KMemFree((LPVOID)pControlBlock,KMEM_SIZE_TYPE_4K,dwStackSize); //Free the memory. } return; }
static DWORD memrels(__CMD_PARA_OBJ* lpCmdObj) { DWORD dwMemAddr = 0; if(NULL == lpCmdObj) return IOCTRL_TERMINAL; if(lpCmdObj->byParameterNum < 2) //Not enough parameters. { PrintLine("Please input the memory address to be released."); return IOCTRL_NORMAL; } if(!Str2Hex(lpCmdObj->Parameter[1],&dwMemAddr)) //Invalid address value. { PrintLine("Please input the address correctly."); return IOCTRL_NORMAL; } KMemFree((LPVOID)dwMemAddr,KMEM_SIZE_TYPE_ANY,0); //Release the memory. return IOCTRL_NORMAL; }
/* * 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; }
//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; }
//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; }
//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; }
//Window procedure of bitmap button control. static DWORD BmpButtonWndProc(HANDLE hWnd,UINT message,WORD wParam,DWORD lParam) { HANDLE hDC = GetClientDC(hWnd); __BITMAP_BUTTON* pButton = NULL; __WINDOW_MESSAGE msg; if(NULL == hWnd) { return 0; } pButton = (__BITMAP_BUTTON*)GetWindowExtension(hWnd); if(NULL == pButton) { return DefWindowProc(hWnd,message,wParam,lParam); } switch(message) { case WM_CREATE: DrawButtonNormal(hDC,pButton); DrawButtonFrame(hDC,pButton); break; case WM_DRAW: DrawButtonNormal(hDC,pButton); DrawButtonFrame(hDC,pButton); break; case WM_LBUTTONDOWN: if(pButton->dwBmpBtnStatus == BUTTON_STATUS_PRESSED) //Already in pressed status. { break; } pButton->dwBmpBtnStatus = BUTTON_STATUS_PRESSED; DrawButtonFrame(hDC,pButton); break; case WM_MOUSEMOVE: if(pButton->dwBmpBtnStatus == BUTTON_STATUS_PRESSED) //Button is hold. { pButton->dwBmpBtnStatus = BUTTON_STATUS_NORMAL; DrawButtonFrame(hDC,pButton); } break; case WM_LBUTTONUP: if(pButton->dwBmpBtnStatus == BUTTON_STATUS_NORMAL) //Already in normal status. { break; } pButton->dwBmpBtnStatus = BUTTON_STATUS_NORMAL; DrawButtonFrame(hDC,pButton); //Send button pressed message to it's parent. msg.hWnd = GetParentWindow(hWnd); msg.message = WM_COMMAND; msg.wParam = pButton->dwBmpButtonId; msg.lParam = 0; SendWindowMessage(msg.hWnd,&msg); break; case WM_CLOSE: case WM_DESTROY: //Release the common control specific resource,the system level resource, //such as window resource,will be released by DefWindowProc routine. KMemFree(pButton,KMEM_SIZE_TYPE_ANY,0); SetWindowExtension(hWnd,NULL); break; } return DefWindowProc(hWnd,message,wParam,lParam); }
//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; }
//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; }
// //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; }
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; }
//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; }
//Create a DC object. HANDLE CreateDeviceContext(DWORD dwDCType,HANDLE hDevice,HANDLE hWnd,__REGION* pRegion) { __DC* pDC = NULL; HANDLE hPen = NULL; HANDLE hBrush = NULL; HANDLE hFont = NULL; BOOL bResult = FALSE; __WINDOW* pWnd = (__WINDOW*)hWnd; if(NULL == hDevice) { return NULL; } pDC = (__DC*)KMemAlloc(sizeof(__DC),KMEM_SIZE_TYPE_ANY); if(NULL == pDC) //Can not allocate memory. { goto __TERMINAL; } //Now create pen,font,brush objects. hPen = CreatePen(0,1,COLOR_BLACK); if(NULL == hPen) { goto __TERMINAL; } hFont = CreateFont(DEFAULT_FONT_WIDTH,DEFAULT_FONT_HEIGHT, DEFAULT_FONT_CHSPACE,DEFAULT_FONT_LNSPACE); if(NULL == hFont) { goto __TERMINAL; } hBrush = CreateBrush(FALSE,pWnd->clrBackground); if(NULL == hBrush) { goto __TERMINAL; } //Initialize DC object. pDC->dwDCType = dwDCType; pDC->pBrush = (__BRUSH*)hBrush; pDC->pFont = (__FONT*)hFont; pDC->hWindow = hWnd; pDC->pPen = (__PEN*)hPen; pDC->pRegion = pRegion; if(dwDCType | DC_TYPE_SCREEN) { pDC->pVideo = (__VIDEO*)hDevice; } else { pDC->hOther = hDevice; } bResult = TRUE; __TERMINAL: if(!bResult) { if(pDC) { KMemFree(pDC,KMEM_SIZE_TYPE_ANY,0); } if(hPen) { DestroyPen(hPen); } if(hBrush) { DestroyBrush(hBrush); } if(hFont) { DestroyFont(hFont); } pDC = NULL; } return (HANDLE)pDC; }
// //Create a thread,and put the thread's control block into array g_pKThreadQueue, //and update the corresponding queue. //If failed,it returns 0,otherwise,returns the created kernal thread's ID. // DWORD CreateKThread(DWORD dwStackSize, //Thread's stack size. DWORD dwFlags, //Flags. DWORD dwPriority, //Priority. LPKTHREAD_ROUTINE pStartAddress, //Start running address. LPVOID pData, //Parameter. LPVOID /*pReserved*/) //Reserved. { DWORD dwKThreadID = 0x00000000; struct __KTHREAD_CONTROL_BLOCK* pControlBlock = NULL; LPVOID pStackPointer = NULL; BOOL bFind = FALSE; RoundTo4k(dwStackSize); //Round the stack size to 4k times. pControlBlock = (struct __KTHREAD_CONTROL_BLOCK*) KMemAlloc(dwStackSize,KMEM_SIZE_TYPE_4K); if(NULL == pControlBlock) //If can not allocate the memory. { return dwKThreadID; } MemZero((LPVOID)pControlBlock,dwStackSize); //Zero the memory allocated just now. pControlBlock->pKThreadRoutine = pStartAddress; //Members initialization. pControlBlock->dwKThreadPriority = dwPriority; pControlBlock->pData = pData; pControlBlock->wCurrentMsgNum = 0x0000; pControlBlock->wHeader = 0x0000; pControlBlock->wTrial = 0x0000; //DisableInterrupt(); //Disable interrupt. // **************** for(dwKThreadID = 0;dwKThreadID < MAX_KTHREAD_NUM;dwKThreadID ++) { if(0 == g_bKThreadQueueStatus[dwKThreadID]) //Find a free control block slot. { bFind = TRUE; break; } } if(FALSE == bFind) //If can not find a free control block slot. { KMemFree((LPVOID)pControlBlock,KMEM_SIZE_TYPE_4K,dwStackSize); //Free the memory. return 0L; } DisableInterrupt(); //Disable interrupt. //****************** g_pKThreadQueue[dwKThreadID] = pControlBlock; g_bKThreadQueueStatus[dwKThreadID] = 1; //Set the occupied flag. dwKThreadID ++; //Increase the KThreadID. pControlBlock->dwKThreadID = dwKThreadID; pControlBlock->dwStackSize = dwStackSize; switch(dwFlags) //Update the proper kernal thread queues. //Insert the created kernal thread into //the status queue. { case KTHREAD_STATUS_BLOCKED: //Insert into blocked queue. pControlBlock->dwKThreadStatus = KTHREAD_STATUS_BLOCKED; pControlBlock->pNext = g_pBlockedQueue; g_pBlockedQueue = pControlBlock; break; case KTHREAD_STATUS_SUSPEND: //Insert it into suspended queue. pControlBlock->dwKThreadStatus = KTHREAD_STATUS_SUSPEND; pControlBlock->pNext = g_pSuspendQueue; g_pSuspendQueue = pControlBlock; break; default: //All other status,insert into ready queue. case KTHREAD_STATUS_READY: case KTHREAD_STATUS_RUNNING: pControlBlock->dwKThreadStatus = KTHREAD_STATUS_READY; pControlBlock->pNext = g_pReadyQueue; g_pReadyQueue = pControlBlock; break; } #ifdef __I386__ //Update the x86 CPU's context. pControlBlock->dwESP = (DWORD)pControlBlock + dwStackSize; pControlBlock->dwEIP = (DWORD)pStartAddress; pControlBlock->dwEFlags = 512; //***************************** #else #endif EnableInterrupt(); //Enable interrupt. //***************** return dwKThreadID; }
//setif command's implementation. static DWORD setif(__CMD_PARA_OBJ* lpCmdObj) { DWORD dwRetVal = SHELL_CMD_PARSER_FAILED; __ETH_IP_CONFIG* pifConfig = NULL; BYTE index = 1; char* errmsg = " Error: Invalid parameter(s).\r\n"; BOOL bAddrOK = FALSE; BOOL bMaskOK = FALSE; //Allocate a association information object,to contain user specified associating info. //This object will be destroyed by ethernet thread. pifConfig = (__ETH_IP_CONFIG*)KMemAlloc(sizeof(__ETH_IP_CONFIG),KMEM_SIZE_TYPE_ANY); if(NULL == pifConfig) { goto __TERMINAL; } //Initialize to default value. memset(pifConfig,0,sizeof(__ETH_IP_CONFIG)); if(lpCmdObj->byParameterNum <= 1) { goto __TERMINAL; } //Parse command line. while(index < lpCmdObj->byParameterNum) { if(strcmp(lpCmdObj->Parameter[index],"/d") == 0) //Key of association. { index ++; if(index >= lpCmdObj->byParameterNum) { _hx_printf(errmsg); goto __TERMINAL; } if(strcmp(lpCmdObj->Parameter[index],"enable") == 0) //Enable DHCP functions. { pifConfig->dwDHCPFlags = ETH_DHCPFLAGS_ENABLE; } else if(strcmp(lpCmdObj->Parameter[index],"disable") == 0) //Disable DHCP functions. { pifConfig->dwDHCPFlags = ETH_DHCPFLAGS_DISABLE; } else if(strcmp(lpCmdObj->Parameter[index],"restart") == 0) //Restart DHCP. { pifConfig->dwDHCPFlags = ETH_DHCPFLAGS_RESTART; } else if(strcmp(lpCmdObj->Parameter[index],"release") == 0) //Release DHCP configurations. { pifConfig->dwDHCPFlags = ETH_DHCPFLAGS_RELEASE; } else { _hx_printf(errmsg); goto __TERMINAL; } } else if(strcmp(lpCmdObj->Parameter[index],"/a") == 0) //Set IP address. { index ++; if(index >= lpCmdObj->byParameterNum) { _hx_printf(errmsg); goto __TERMINAL; } pifConfig->ipaddr.addr = inet_addr(lpCmdObj->Parameter[index]); bAddrOK = TRUE; } else if(strcmp(lpCmdObj->Parameter[index],"/m") == 0) //Set IP subnet mask. { index ++; if(index >= lpCmdObj->byParameterNum) { _hx_printf(errmsg); goto __TERMINAL; } pifConfig->mask.addr = inet_addr(lpCmdObj->Parameter[index]); bMaskOK = TRUE; } else if(strcmp(lpCmdObj->Parameter[index],"/g") == 0) //Set default gateway. { index ++; if(index >= lpCmdObj->byParameterNum) { _hx_printf(errmsg); goto __TERMINAL; } pifConfig->defgw.addr = inet_addr(lpCmdObj->Parameter[index]); } else //Default parameter as interface's name. { if(strlen(lpCmdObj->Parameter[index]) < 2) //Invalid interface name. { _hx_printf(errmsg); goto __TERMINAL; } //pifConfig->ifName[0] = lpCmdObj->Parameter[index][0]; //pifConfig->ifName[1] = lpCmdObj->Parameter[index][1]; strcpy(pifConfig->ethName,lpCmdObj->Parameter[index]); } index ++; } //If IP address and mask are all specified correctly,then assume the DHCP //functions will be disabled. if(bAddrOK && bMaskOK) { pifConfig->dwDHCPFlags = ETH_DHCPFLAGS_DISABLE; } //If only specify one parameter without another,it's an error. if((bAddrOK && !bMaskOK) || (!bAddrOK & bMaskOK)) { _hx_printf(errmsg); goto __TERMINAL; } //Everything is OK,send a message to EthernetManager to launch the //modification. EthernetManager.ConfigInterface(pifConfig->ethName,pifConfig); dwRetVal = SHELL_CMD_PARSER_SUCCESS; __TERMINAL: if(pifConfig) //Should release the config object. { KMemFree(pifConfig,KMEM_SIZE_TYPE_ANY,0); } return dwRetVal; }
//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; }
// //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; }
//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; }
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; }
//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 }
// //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; }
/* * 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; }
//The implementation code of CreateButton. HANDLE CreateBitmapButton(HANDLE hParent,TCHAR* pszText, DWORD dwButtonId,int x,int y, int cxbmp,int cybmp, LPVOID pBitmap, LPVOID pExtension) { HANDLE hButton = NULL; __WINDOW* pBtnWnd = NULL; __BITMAP_BUTTON* pButton = NULL; BOOL bResult = FALSE; __WINDOW* pParent = (__WINDOW*)hParent; __WINDOW_MESSAGE msg; int height = 0; //Total width. int width = 0; //Total height. int txtheight = 0; int txtwidth = 0; int ntxtlen = 0; HANDLE hDC = NULL; if(NULL == hParent) //Invalid. { return NULL; } hDC = GetWindowDC(hParent); pButton = (__BITMAP_BUTTON*)KMemAlloc(sizeof(__BITMAP_BUTTON),KMEM_SIZE_TYPE_ANY); if(NULL == pButton) { goto __TERMINAL; } //Initialize button. pButton->dwBmpButtonId = dwButtonId; ntxtlen = strlen(pszText); if(ntxtlen >= BMPBTN_TEXT_LENGTH - 1) //Text too long. { goto __TERMINAL; } strcpy(pButton->ButtonText,pszText); pButton->x = x; //+ pParent->xclient; pButton->y = y; //+ pParent->yclient; txtheight = GetTextMetric(hDC,pszText,TM_HEIGHT); txtheight += TXT_MARGIN; //Uper margin. txtheight += TXT_MARGIN; //Bottom margin. pButton->cy = cybmp + txtheight; pButton->txtheight = txtheight; width = GetTextMetric(hDC,pszText,TM_WIDTH); if(width > cxbmp - TXT_MARGIN * 2) //Too long. { goto __TERMINAL; } pButton->cx = cxbmp; pButton->xtxt = (pButton->cx - width) / 2; pButton->ytxt = cybmp + TXT_MARGIN; pButton->txtwidth = width; pButton->dwBmpBtnStatus = BUTTON_STATUS_NORMAL; pButton->pBmpData = pBitmap; pButton->pButtonExtension = pExtension; //Set default button colors. pButton->FaceClr = DEFAULT_BMPBTN_FACECOLOR; pButton->TxtBackground = DEFAULT_BMPBTN_TXTBACKGROUND; pButton->TxtColor = DEFAULT_BMPBTN_TXTCOLOR; //Allocate memory for bitmap data. if(pBitmap) { pButton->pBmpData = KMemAlloc(cxbmp * cybmp * sizeof(__COLOR),KMEM_SIZE_TYPE_ANY); if(NULL == pButton->pBmpData) { goto __TERMINAL; } memcpy(pButton->pBmpData,pBitmap,cxbmp * cybmp * sizeof(__COLOR)); } //Create the button window. hButton = CreateWindow(0, //Without any caption and border. NULL, //Without title. pButton->x + pParent->x, pButton->y + pParent->y, pButton->cx, pButton->cy, BmpButtonWndProc, hParent, NULL, GlobalParams.COLOR_BTNFACE, NULL); if(NULL == hButton) { goto __TERMINAL; } pBtnWnd = (__WINDOW*)hButton; pBtnWnd->lpWndExtension = (LPVOID)pButton; //Save button information to window's ext. //Send WM_PAINT message to button to re-draw itself. msg.hWnd = hButton; msg.message = WM_PAINT; msg.wParam = 0; msg.lParam = 0; SendWindowMessage(hButton,&msg); bResult = TRUE; __TERMINAL: if(!bResult) { if(pButton) { if(pButton->pBmpData) { KMemFree(pButton->pBmpData,KMEM_SIZE_TYPE_ANY,0); } KMemFree(pButton,KMEM_SIZE_TYPE_ANY,0); } if(hButton) { CloseWindow(hButton); } hButton = NULL; } return hButton; }