日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

WinCE6.0中应用程序如何直接访问物理空间

發(fā)布時(shí)間:2023/12/10 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WinCE6.0中应用程序如何直接访问物理空间 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?在實(shí)際開發(fā)過(guò)程中,經(jīng)常希望能在應(yīng)用程序中直接讀寫設(shè)備的物理空間。以前在做WinCE6.0下的MEMMgr時(shí)通過(guò)秘密加載一個(gè)內(nèi)核態(tài)驅(qū)動(dòng)實(shí)現(xiàn)了這個(gè)需求。但這種方式有一個(gè)明顯的缺陷,每次讀寫都必須經(jīng)由它才能完成。如果只是讀取GPIO,那問題不算大。如果想通過(guò)這種方式實(shí)現(xiàn)視頻播放的加速就比較困難了。估計(jì)非但不能加速,反而會(huì)變得更慢。

????? 早先曾與ZL仔細(xì)的討論過(guò)這個(gè)問題,他當(dāng)時(shí)在WinCE6.0上移植TCPMP,發(fā)現(xiàn)播放視頻不太流暢,于是想通過(guò)直接寫顯存進(jìn)行加速。目的很明確,在應(yīng)用中申請(qǐng)一段虛擬空間,通過(guò)某種方法將其映射到顯存上,視頻解碼過(guò)程中直接往映射過(guò)的虛擬空間上寫。這種方法與使用GAPI有一點(diǎn)類似。

????? 實(shí)現(xiàn)這個(gè)需求,需要用到函數(shù)VirtualCopyEx()。看看幫助中關(guān)于它的說(shuō)明,This function dynamically maps a virtual address to a physical address by creating a new page-table entry.This function is callable in kernel mode and in user mode, when the source and destination process handles are the active process.This function is similar to?VirtualCopy, except?VirtualCopyEx?requires handles to the source and destination process.

????? 據(jù)此基本可以確定,我們的確可以在應(yīng)用中申請(qǐng)一段虛擬空間,然后通過(guò)這個(gè)函數(shù)將其映射到某段物理空間上。其中目標(biāo)進(jìn)程是我們的應(yīng)用,而源進(jìn)程是NK.exe。為了實(shí)現(xiàn)在NK.exe中執(zhí)行VirtualCopyEx(),可以加載一個(gè)內(nèi)核態(tài)的驅(qū)動(dòng)。更為方便的方法是移植一個(gè)OALIOCTL,并在IOControl()中添加一個(gè)case。這樣,應(yīng)用程序在做內(nèi)存映射時(shí)就無(wú)需打開某個(gè)流驅(qū)動(dòng),直接調(diào)用KernelIoControl()即可。

????? OALIOCTL中添加的關(guān)鍵代碼如下。?

?1?typedef?struct?{
?2?????void*????pvDestMem;
?3?????DWORD????dwPhysAddr;
?4?????DWORD????dwSize;
?5?}?VIRTUAL_COPY_EX_DATA;
?6?
?7?#define?IOCTL_VIRTUAL_COPY_EX?CTL_CODE?(FILE_DEVICE_UNKNOWN,3333,METHOD_BUFFERED,FILE_ANY_ACCESS)
?8?
?9?
10?case?IOCTL_VIRTUAL_COPY_EX:
11?{
12?????VIRTUAL_COPY_EX_DATA?*p?=?(VIRTUAL_COPY_EX_DATA*)pInBuf;
13?????HANDLE?hDst?=?(HANDLE)GetDirectCallerProcessId();
14?????HANDLE?hSrc?=?(HANDLE)GetCurrentProcessId();
15?????fRet?=?VirtualCopyEx(hDst,p->pvDestMem,hSrc,(LPVOID)p->dwPhysAddr,p->dwSize,
16?     PAGE_READWRITE|PAGE_PHYSICAL|PAGE_NOCACHE);
17?}break;

?????? 應(yīng)用程序中進(jìn)行內(nèi)存映射的關(guān)鍵代碼如下。

?1?volatile?LPVOID?GetVirtual(DWORD?dwPhyBaseAddress,?DWORD?dwSize)
?2?{
?3?????volatile?LPVOID?pVirtual;
?4?????VIRTUAL_COPY_EX_DATA?vced;
?5?????
?6?????if(dwPhyBaseAddress&0xFFF)
?7?????{
?8?????????return?NULL;
?9?????}
10?????vced.dwPhysAddr?=?dwPhyBaseAddress>>8;
11?????pVirtual?=?VirtualAlloc(0,dwSize,MEM_RESERVE,PAGE_NOACCESS);
12?????vced.pvDestMem?=?pVirtual;
13?????vced.dwSize?=?dwSize;
14?????KernelIoControl(IOCTL_VIRTUAL_COPY_EX,&vced,?sizeof(vced),?NULL,?NULL,?NULL);
15?????return?pVirtual;
16?}
17?
18?//?WinCE6.0模擬器中應(yīng)用程序直接寫屏
19?PBYTE?pLCDBuf?=?(PBYTE)GetVirtual(0x33f00000,0x100000);
20?memset(pLCDBuf,0,0x100000);
21?

?????? 這種方法在WinCE6.0的模擬器中測(cè)試了一下,能達(dá)到預(yù)期的效果。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的WinCE6.0中应用程序如何直接访问物理空间的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。