锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 1) APCs鍏佽鐢ㄦ埛紼嬪簭鍜岀郴緇熷厓浠跺湪涓涓繘紼嬬殑鍦板潃絀洪棿鍐呮煇涓嚎紼嬬殑涓婁笅鏂囦腑鎵ц浠g爜銆?br>2) I/O綆$悊鍣ㄤ嬌鐢ˋPCs鏉ュ畬鎴愪竴涓嚎紼嬪彂璧風殑寮傛鐨処/O鎿嶄綔銆備緥濡傦細褰撲竴涓澶囬┍鍔ㄨ皟鐢↖oCompleteRequest鏉ラ氱煡I/O綆$悊鍣紝瀹冨凡緇忕粨鏉熷鐞嗕竴涓紓姝/O璇鋒眰鏃訛紝I/O綆$悊鍣ㄦ帓闃熶竴涓猘pc鍒板彂璧瘋姹傜殑綰跨▼銆傜劧鍚庣嚎紼嬪湪涓涓緝浣嶪RQL綰у埆錛屾潵鎵цAPC. APC鐨勪綔鐢ㄦ槸浠庣郴緇熺┖闂存嫹璐滻/O鎿嶄綔緇撴灉鍜岀姸鎬佷俊鎭埌綰跨▼铏氭嫙鍐呭瓨絀洪棿鐨勪竴涓紦鍐蹭腑銆?br>3) 浣跨敤APC鍙互寰楀埌鎴栬呰緗竴涓嚎紼嬬殑涓婁笅鏂囧拰鎸傝搗綰跨▼鐨勬墽琛屻?/p>
涓婇潰鏄綉涓婃壘鏉ョ殑錛屼笅闈㈡槸MSDN涓婄殑璇存槑錛?/p>
Each thread has its own APC queue. An application queues an APC to a thread by calling the QueueUserAPC function. The calling thread specifies the address of an APC function in the call to QueueUserAPC. The queuing of an APC is a request for the thread to call the APC function. 榪樺厛鐪嬩竴涓嬮偅浜涢噸瑕佺粨鏋勶細 kd> dt KTHREAD ………… 涓婇潰綰㈣壊閮ㄥ垎鏄疉PC鏈哄埗鐢ㄥ埌鐨勫嚑涓瓧孌碉紒錛?/p>
kd> dt _KAPC_STATE 鏄劇劧錛岃繖閲岀殑 ApcListHead 灝辨槸 APC 闃熷垪澶淬備笉榪囪繖鏄釜澶у皬涓?2 鐨勬暟緇勶紝璇存槑瀹為檯 SavedApcState涔熸槸涓猒KAPC_STATE緇撴瀯錛屽綋褰撳墠紼嬫殏鏃?#8220;鎸傞潬(Attach)”鍒板彟涓涓繘紼嬬殑鍦板潃絀洪棿鐨勬椂渚紝ApcState灝辨嫹璐濆埌SavedApcState鏆傛椂瀛樻斁錛?/p>
褰撶劧錛岃繕瑕佹湁鐘舵佷俊鎭鏄庢湰綰跨▼褰撳墠鏄浜?#8220;鍘熷鐜”榪樻槸“鎸傞潬鐜”錛岃繖灝辨槸 ApcStateIndex 鐨勪綔鐢紝浠g爜涓負 ApcStateIndex鐨勫煎畾涔変簡涓縐嶆灇涓劇被鍨嬶細 typedef enum _KAPC_ENVIRONMENT { 瀹為檯鍙敤浜?ApcStateIndex 鐨勫彧鏄?OriginalApcEnvironment鍜?AttachedApcEnvironment銆?/p>
KAPC_STATE 鎸囬拡鏁扮粍 ApcStatePointer[2]錛屽氨鐢ˋpcStateIndex 鐨勫綋鍓嶅間綔涓轟笅鏍囷紝鑰屾暟緇勪腑鐨勬寚閽堝垯鏍規嵁鎯呭喌鍙互鍒嗗埆鎸囧悜涓や釜APC_STATE 鏁版嵁緇撴瀯涓殑涓涓?/p>
kd> dt _KAPC ;APC瀵硅薄 KernelRoutine銆丷undownRoutine銆丯ormalRoutine銆傚叾涓彧鏈?NormalRoutine鎵嶆寚鍚?鎵ц)APC 鍑芥暟鐨勮姹傝呮墍鎻愪緵鐨勫嚱鏁幫紝鍏朵綑涓や釜閮芥槸杈呭姪鎬х殑錛?/p>
NTKERNELAPI 榪欎釜鍑芥暟涓昏鐢ㄦ潵鍒濆鍖朅pc錛坃KAPC錛夎繖涓粨鏋勭殑錛屽鏋淓nvironment==CurrentApcEnvironment,Apc->ApcStateIndex灝辯敱KTHREAD涓殑ApcStateIndex鍐沖畾錛屼絾Environment涓嶈兘澶т簬KTHREAD涓殑ApcStateIndex錛?/p>
鏈鍚庯紝APC 璇鋒眰鐨勬ā寮廝rocessorMode錛屼絾鏄湁涓緥澶栵紝閭e氨鏄細濡傛灉鎸囬拡NormalRoutine 涓?0錛岄偅涔堝疄闄呯殑妯″紡鍙樻垚浜?KernelMode銆傝繖鏄洜涓哄湪榪欑鎯呭喌涓嬫病鏈夌敤鎴風┖闂碅PC鍑芥暟鍙互鎵ц錛?鍞竴灝嗗緱鍒版墽琛岀殑鏄疜ernelRoutine錛?/p>
鏈鍚庯紝KeInitializeApc 璁劇疆Inserted鍩熶負FALSE銆傜劧鑰屽垵濮嬪寲APC瀵硅薄錛屽茍娌℃湁鎶婂畠瀛樻斁鍒扮浉搴旂殑APC闃熷垪涓?/p>
鎹瓵PC璇鋒眰鐨勫叿浣撴儏鍐碉紝鏈夋椂鍊欒鎻掑湪闃熷垪鐨勫墠澶達紝涓鑸垯鎸傚湪闃熷垪鐨勫熬閮ㄣ?/p>
_KiServiceExit: cli ; disable interrupts ; EXIT_ALL NoRestoreSegs, NoRestoreVolatile ;榪欎釜瀹忎互鍚庡啀璁?/p>
DISPATCH_USER_APC macro TFrame, ReturnCurrentEax test byte ptr [TFrame]+TsEflags+2, EFLAGS_V86_MASK/010000h ; is previous mode v86? mov ebx, TFrame ;DISPATCH_USER_APC ebp, ReturnCurrentEax錛屾樉鐒惰繖閲屾槸緙栬瘧鐨勶紒 ; sti ; Allow higher priority ints ; stdCall _KiDeliverApc, <1, 0, ebx> ;1灝辨槸UserMode pop ecx ; (ecx) = OldIrql ifnb <ReturnCurrentEax> ;鍚屼笂鍒嗘瀽 cli ALIGN 4 榪欐浠g爜涓昏媯鏌ワ細 鍗沖皢榪斿洖鐨勬槸鍚︾敤鎴風┖闂淬?br>鏄惁鏈夌敤鎴稟PC璇鋒眰姝e湪絳夊緟鎵ц 鏉′歡絎﹀悎鎵嶇敤KiDeliverApc鐪熸鎶曢扐PC銆傛敞鎰忎唬鐮乯mp b錛屽ソ鍍忓湪榪斿洖鐢ㄦ埛絀洪棿鍓岾iDeliverApc浼氳寰幆璋冪敤鐩村埌娌℃湁user APC錛屽叾瀹炰笉鏄殑錛孠iDeliverApc姣忓鐞嗗畬涓涓猆ser APC灝辨妸UserApcPending娓呴浂錛屾墍浠ser APCs鍦ㄨ繑鍥炵敤鎴風┖闂存椂榪樻槸鍙兘鎶曢掍竴嬈★紒KiDeliverApc涓敤while澶勭悊瀹屾墍鏈塊ernel Mode APCs錛屼絾User Mode APC鍗村彧澶勭悊涓涓紒浜嬪疄涓奤ser APC鐨勬姇閫掓槸寰堢壒孌婄殑錛屼互鍚庝細璁插埌錛岃屼笖姣忔鍙兘鎶曢掍竴嬈★紒 KiDeliverApc ( 榪欎釜鍑芥暟閲岄潰榪樻瘮杈冨鏉傦紝浠g爜涓嶅笘浜嗐?/p>
鍙傛暟PreviousMode琛ㄧず闇瑕?#8220;鎶曢?#8221;鍝竴縐?APC錛屽彲浠ユ槸UserMode錛屼篃鍙互鏄疜ernelMode銆備笉榪囷紝KernelMode 紜疄琛ㄧず鍙姹傛墽琛屽唴鏍?APC錛岃孶serMode 鍗磋〃紺哄湪鎵ц鍐呮牳 APC 涔嬪鍐嶆墽琛岀敤鎴稟PC銆?/p>
The Windows operating system uses three kinds of APCs: User APCs Normal kernel APCs _KAPC.ApcMode==KernelMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine!=NULL Special kernel APCs _KAPC.ApcMode==KernelMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine==NULL 鏈変竴鐐瑰畠浠殑_KAPC.KernelRoutine鑲畾涓嶄負絀恒傚茍涓旓紝濡傛灉NormolRoutine涔熶笉涓虹┖錛岄偅涔圞ernelRoutine閮藉湪NormolRoutine琚皟鐢ㄥ墠琚皟鐢紒錛?/p>
涓婃枃涓鍒版姇閫扷ser Mode APCs鏄緢鐗規畩鐨勶紝閬撶悊寰堢畝鍗曪紝鍥犱負User Mode APC鏄痳ing3涓嬬殑鍥炶皟鍑芥暟錛屾樉鐒秗ing0涓殑KiDeliverAPC錛堬級涓嶈兘鍍廗ernel Mode APC閭f牱鐩存帴call錛屽繀欏昏鍏堝洖鍒皉ing3鐜涓嬨傚綋鐒朵笉鑳藉儚鏅氭儏鍐甸偅鏍瘋繑鍥烇紙鍚﹀垯灝卞洖鍒皉ing3緋葷粺璋冪敤鐨勫湴鏂逛簡錛夛紝鍙湁涓涓姙娉曪紝閭e氨鏄慨鏀筎rapFrame 錛屾楠楃郴緇熻繑鍥?#8220;APC鍥炶皟鍑芥暟”錛並iInitializeUserApc灝辨槸榪欎箞鍋氱殑錛?/p>
璇ュ嚱鏁伴鍏堟妸TrapFrame杞寲涓篊ontextFrame錛岀劧鍚庣Щ鍔ㄧ敤鎴鋒丒SP鎸囬拡錛屽垎閰嶅ぇ綰izeof錛圕ONTEXT錛?sizeof錛圞APC_RECORD錛変釜瀛楄妭: UserStack-> …… KAPC_RECORD …… …… CONTEXT TopOfStack-> …… KAPC_RECORD灝辨槸KiInitializeUserApc鐨勬渶鍚庡洓涓弬鏁?/p>
nt!_KAPC_RECORD +0x000 NormalRoutine : Ptr32 void +0x004 NormalContext : Ptr32 Void +0x008 SystemArgument1 : Ptr32 Void +0x00c SystemArgument2 : Ptr32 Void CONTEXT緇撴瀯涓昏鏉ュ瓨鏀捐淇敼鍓嶇殑TrapFrame錛屼箣鎵浠ョ敤CONTEXT緇撴瀯鏄窡APC鍑芥暟榪斿洖鏈夊叧錛?/p>
TrapFrame->HardwareEsp = UserStack; TrapFrame->Eip = (ULONG)KeUserApcDispatcher; TrapFrame->ErrCode = 0; 浠庝笂闈㈢殑浠g爜鐪嬪埌紜疄淇敼浜員rapFrame錛屽茍涓旇繑鍥炲埌鐨勬槸ring3涓嬬殑KeUserApcDispatcher錛屽垰鎵嶈鐨刜KAPC_RECORD鍏跺疄涔熸槸瀹冪殑鍙傛暟錛佺湡姝f垜浠殑User APC鍥炶皟鍑芥暟鏄敱KeUserApcDispatcher璋冪敤鐨勶紒 .func KiUserApcDispatcher@16 .globl _KiUserApcDispatcher@16 /* Setup SEH stack */ lea eax, [esp+CONTEXT_ALIGNED_SIZE+16] mov ecx, fs:[TEB_EXCEPTION_LIST] mov edx, offset _KiUserApcExceptionHandler mov [eax], ecx mov [eax+4], edx /* Enable SEH */ mov fs:[TEB_EXCEPTION_LIST], eax /* Put the Context in EDI */ pop eax lea edi, [esp+12] /* Call the APC Routine */ call eax /* Restore exception list */ mov ecx, [edi+CONTEXT_ALIGNED_SIZE] mov fs:[TEB_EXCEPTION_LIST], ecx /* Switch back to the context */ push 1 ; TestAlert push edi ;edi->CONTEXT緇撴瀯 call _ZwContinue@8 ;;涓嶄細榪斿洖鍒拌繖閲岀殑 涓婇潰鐨勪唬鐮佸茍涓嶉毦鐞嗚В錛屾垜浠殑User APC鍥炶皟鍑芥暟榪斿洖鍚庯紝绔嬪嵆璋冪敤浜哯wContinue錛岃繖鏄釜ntdll涓殑瀵煎嚭鍑芥暟錛岃繖涓嚱鏁板張閫氳繃緋葷粺璋冪敤榪涘叆kernel涓殑NtContinue錛?/p>
NTSTATUS ; NtContinue ( ; IN PCONTEXT ContextRecord, ; IN BOOLEAN TestAlert ; ) ; ; Routine Description: ; ; This routine is called as a system service to continue execution after ; an exception has occurred. Its function is to transfer information from ; the specified context record into the trap frame that was built when the ; system service was executed, and then exit the system as if an exception ; had occurred. ; ; WARNING - Do not call this routine directly, always call it as ; ZwContinue!!! This is required because it needs the ; trapframe built by KiSystemService. ; ; Arguments: ; ; KTrapFrame (ebp+0: after setup) -> base of KTrapFrame ; ; ContextRecord (ebp+8: after setup) = Supplies a pointer to a context rec. ; ; TestAlert (esp+12: after setup) = Supplies a boolean value that specifies ; whether alert should be tested for the previous processor mode. ; ; Return Value: ; ; Normally there is no return from this routine. However, if the specified ; context record is misaligned or is not accessible, then the appropriate ; status code is returned. ; ;-- NcTrapFrame equ [ebp + 0] NcContextRecord equ [ebp + 8] NcTestAlert equ [ebp + 12] align dword cPublicProc _NtContinue ,2 push ebp ;ebp->TrapFrame ; ; Restore old trap frame address since this service exits directly rather ; than returning. ; mov ebx, PCR[PcPrcbData+PbCurrentThread] ; get current thread address mov edx, [ebp].TsEdx ; restore old trap frame address mov [ebx].ThTrapFrame, edx ; ; ; Call KiContinue to load ContextRecord into TrapFrame. On x86 TrapFrame ; is an atomic entity, so we don't need to allocate any other space here. ; ; KiContinue(NcContextRecord, 0, NcTrapFrame) ; mov ebp,esp mov eax, NcTrapFrame mov ecx, NcContextRecord stdCall _KiContinue, <ecx, 0, eax> or eax,eax ; return value 0? jnz short Nc20 ; KiContinue failed, go report error ; ; Check to determine if alert should be tested for the previous processor mode. ; cmp byte ptr NcTestAlert,0 ; Check test alert flag je short Nc10 ; if z, don't test alert, go Nc10 mov al,byte ptr [ebx]+ThPreviousMode ; No need to xor eax, eax. stdCall _KeTestAlertThread, <eax> ; test alert for current thread ;濡傛灉User APCs涓嶄負絀猴紝瀹冧細璁劇疆UserApcPending, ;璺烝lertable鏃犲叧 Nc10: pop ebp ; (ebp) -> TrapFrame mov esp,ebp ; (esp) = (ebp) -> trapframe jmp _KiServiceExit2 ; common exit Nc20: pop ebp ; (ebp) -> TrapFrame mov esp,ebp ; (esp) = (ebp) -> trapframe jmp _KiServiceExit ; common exit stdENDP _NtContinue NtContinue鎶奀ONTEXT緇撴瀯杞寲鎴怲rapFrame錛堝洖澶嶅師鏉ョ殑闄烽槺甯э級錛岀劧鍚庡氨浠嶬iServiceExit2澶勯鍑虹郴緇熻皟鐢紒 ;++ ; ; _KiServiceExit2 - same as _KiServiceExit BUT the full trap_frame ; context is restored ; ;-- public _KiServiceExit2 _KiServiceExit2: cli ; disable interrupts DISPATCH_USER_APC ebp ; ; Exit from SystemService ; EXIT_ALL ; RestoreAll KiServiceExit2璺烱iServiceExit宸笉澶氾紝鍙槸瀹忓弬鏁扮殑涓嶅悓!鍚屾牱濡傛灉榪樻湁User APC鍙堜細榪涘叆涓婃枃鎻忚堪鐨勬儏褰紝鐩村埌娌℃湁User APC錛岃嚦姝ゆ墠浼氳繑鍥炵湡姝e彂璧峰師濮嬬郴緇熻皟鐢ㄧ殑鍦版柟錛?/p>
2
3 using namespace std;
4
5 void AlertError(DWORD err)
6 {
7 LPVOID lpMsgBuf;
8 LPVOID lpDisplayBuf;
9
10 FormatMessage(
11 FORMAT_MESSAGE_ALLOCATE_BUFFER |
12 FORMAT_MESSAGE_FROM_SYSTEM |
13 FORMAT_MESSAGE_IGNORE_INSERTS,
14 NULL,
15 err,
16 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
17 (LPTSTR) &lpMsgBuf,
18 0, NULL );
19
20 lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
21 strlen((char*)lpMsgBuf) + 40);
22 sprintf((char*)lpDisplayBuf,"閿欒鐮? %d\n淇°鎭? %s", err,lpMsgBuf);
23 MessageBox(NULL, (LPCTSTR)lpDisplayBuf, "閿欒", MB_OK|MB_ICONERROR);
24
25 LocalFree(lpMsgBuf);
26 LocalFree(lpDisplayBuf);
27 }
28
29 void GetCommandOutput(char* CmdLine, string& strOutput, bool IncludeErr=false)
30 {
31 strOutput="";
32 SECURITY_ATTRIBUTES sa;
33 HANDLE hRead, hWrite;
34 memset(&sa,0,sizeof(sa));
35 sa.nLength=sizeof(sa);
36 sa.bInheritHandle=TRUE;
37 sa.lpSecurityDescriptor=NULL;
38 if(CreatePipe(&hRead,&hWrite,&sa,0))
39 {
40 STARTUPINFO si;
41 memset(&si,0,sizeof(si));
42 si.cb=sizeof(si);
43 si.hStdOutput=hWrite;
44 si.hStdInput=GetStdHandle(STD_INPUT_HANDLE);
45 si.hStdError=(IncludeErr?hWrite:GetStdHandle(STD_ERROR_HANDLE));
46 si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
47 si.wShowWindow=SW_HIDE;
48
49 PROCESS_INFORMATION pi;
50 if(CreateProcess(NULL,CmdLine,&sa,&sa,TRUE,CREATE_NO_WINDOW|NORMAL_PRIORITY_CLASS,
51 NULL,NULL,&si,&pi))
52 {
53 char szBuf[512];
54 DWORD dwReaded;
55 if(WaitForSingleObject(pi.hProcess,INFINITE)!=WAIT_TIMEOUT)
56 {
57 CloseHandle(hWrite);
58 while(ReadFile(hRead,szBuf,511,&dwReaded,NULL))
59 {
60 szBuf[dwReaded]='\0';
61 strOutput+=szBuf;
62 }
63 }
64 else
65 {
66 cout<<"WaitForSingleObject閿欒;"<<endl;
67 CloseHandle(hWrite);
68 AlertError(GetLastError());
69 }
70 CloseHandle(pi.hThread);
71 CloseHandle(pi.hProcess);
72 }
73 else
74 {
75 cout<<"寤虹珛榪涚▼閿欒;"<<endl;
76 AlertError(GetLastError());
77 }
78 CloseHandle(hRead);
79 }
80 else
81 {
82 cout<<"寤虹珛綆¢亾閿欒;"<<endl;
83 AlertError(GetLastError());
84 }
85 }
86
87 int APIENTRY WinMain(HINSTANCE hInstance,
88 HINSTANCE hPrevInstance,
89 LPSTR lpCmdLine,
90 int nCmdShow)
91 {
92 char szBuf[MAX_PATH+20];
93 wchar_t wcBuf[MAX_PATH];
94 int i, j;
95 string msg;
96
97 GetCommandOutput("svn info --xml",msg);
98 TiXmlDocument *doc = new TiXmlDocument();
99 doc->Parse(msg.c_str());
100 TiXmlNode *node;
101 node=doc->FirstChild("info");
102 if(node==NULL)
103 {
104 MessageBox(NULL,"褰撳墠鐩綍娌℃湁琚玈VN","緇撴灉",MB_OK|MB_ICONINFORMATION);
105 return 0;
106 }
107 node=node->FirstChild("entry");
108 if(node==NULL)
109 {
110 MessageBox(NULL,"褰撳墠鐩綍娌℃湁琚玈VN","緇撴灉",MB_OK|MB_ICONINFORMATION);
111 return 0;
112 }
113 node=node->FirstChild("wc-info");
114 if(node==NULL)
115 {
116 MessageBox(NULL,"褰撳墠鐩綍娌℃湁琚玈VN","緇撴灉",MB_OK|MB_ICONINFORMATION);
117 return 0;
118 }
119 node=node->FirstChild("wcroot-abspath");
120 if(node==NULL)
121 {
122 MessageBox(NULL,"褰撳墠鐩綍娌℃湁琚玈VN","緇撴灉",MB_OK|MB_ICONINFORMATION);
123 return 0;
124 }
125 strcpy(szBuf,node->ToElement()->GetText());
126 delete node;
127 delete doc;
128
129 j=strlen(szBuf);
130 i=MultiByteToWideChar(CP_UTF8,0,szBuf,j,wcBuf,MAX_PATH);
131 wcBuf[i]=static_cast<wchar_t>(0);
132 strcpy(szBuf,"svn relocate file:///");
133 j=strlen(szBuf);
134 i=WideCharToMultiByte(CP_ACP,0,wcBuf,i,&szBuf[j],MAX_PATH,NULL,NULL);
135 szBuf[i+j]=static_cast<char>(0);
136 SetCurrentDirectory(&szBuf[j]);
137
138 i+=j;
139 if((szBuf[i-1]=='\\')||(szBuf[i-1]=='/'))
140 strcat(szBuf,"svn/");
141 else
142 strcat(szBuf,"/svn/");
143 for(i=0,j=strlen(szBuf);i<j;i++)
144 {
145 if(szBuf[i]=='\\')
146 szBuf[i]='/';
147 }
148
149 GetCommandOutput(szBuf,msg,true);
150 MessageBox(NULL,msg.c_str(),"緇撴灉",MB_OK);
151
152 return 0;
153 }
An asynchronous procedure call (APC) is a function that executes asynchronously in the context of a particular thread. When an APC is queued to a thread, the system issues a software interrupt. The next time the thread is scheduled, it will run the APC function. An APC generated by the system is called a kernel-mode APC. An APC generated by an application is called a user-mode APC. A thread must be in an alertable state to run a user-mode APC.
nt!KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY
+0x018 InitialStack : Ptr32 Void
+0x01c StackLimit : Ptr32 Void
+0x020 KernelStack : Ptr32 Void
+0x024 ThreadLock : Uint4B
+0x028 ApcState : _KAPC_STATE
+0x028 ApcStateFill : [23] UChar
+0x03f ApcQueueable : UChar
+0x040 NextProcessor : UChar
+0x041 DeferredProcessor : UChar
+0x042 AdjustReason : UChar
+0x043 AdjustIncrement : Char
+0x044 ApcQueueLock : Uint4B
+0x048 ContextSwitches : Uint4B
+0x04c State : UChar
+0x04d NpxState : UChar
+0x04e WaitIrql : UChar
+0x04f WaitMode : Char
+0x050 WaitStatus : Int4B
+0x054 WaitBlockList : Ptr32 _KWAIT_BLOCK
+0x054 GateObject : Ptr32 _KGATE
+0x058 Alertable : UChar
+0x059 WaitNext : UChar
+0x05a WaitReason : UChar
+0x05b Priority : Char
+0x05c EnableStackSwap : UChar
+0x05d SwapBusy : UChar
+0x05e Alerted : [2] UChar
+0x060 WaitListEntry : _LIST_ENTRY
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 Queue : Ptr32 _KQUEUE
+0x06c WaitTime : Uint4B
+0x070 KernelApcDisable : Int2B
+0x072 SpecialApcDisable : Int2B
+0x070 CombinedApcDisable : Uint4B
+0x074 Teb : Ptr32 Void
+0x078 Timer : _KTIMER
+0x078 TimerFill : [40] UChar
+0x0a0 AutoAlignment : Pos 0, 1 Bit
+0x0a0 DisableBoost : Pos 1, 1 Bit
+0x0a0 ReservedFlags : Pos 2, 30 Bits
+0x0a0 ThreadFlags : Int4B
+0x0a8 WaitBlock : [4] _KWAIT_BLOCK
+0x0a8 WaitBlockFill0 : [23] UChar
+0x0bf SystemAffinityActive : UChar
+0x0a8 WaitBlockFill1 : [47] UChar
+0x0d7 PreviousMode : Char
+0x0a8 WaitBlockFill2 : [71] UChar
+0x0ef ResourceIndex : UChar
+0x0a8 WaitBlockFill3 : [95] UChar
+0x107 LargeStack : UChar
+0x108 QueueListEntry : _LIST_ENTRY
+0x110 TrapFrame : Ptr32 _KTRAP_FRAME
+0x114 CallbackStack : Ptr32 Void
+0x118 ServiceTable : Ptr32 Void
+0x11c ApcStateIndex : UChar
+0x11d IdealProcessor : UChar
+0x11e Preempted : UChar
+0x11f ProcessReadyQueue : UChar
+0x120 KernelStackResident : UChar
+0x121 BasePriority : Char
+0x122 PriorityDecrement : Char
+0x123 Saturation : Char
+0x124 UserAffinity : Uint4B
+0x128 Process : Ptr32 _KPROCESS
+0x12c Affinity : Uint4B
+0x130 ApcStatePointer : [2] Ptr32 _KAPC_STATE
+0x138 SavedApcState : _KAPC_STATE
+0x138 SavedApcStateFill : [23] UChar
+0x14f FreezeCount : Char
+0x150 SuspendCount : Char
+0x151 UserIdealProcessor : UChar
+0x152 CalloutActive : UChar
+0x153 Iopl : UChar
+0x154 Win32Thread : Ptr32 Void
+0x158 StackBase : Ptr32 Void
+0x15c SuspendApc : _KAPC
+0x15c SuspendApcFill0 : [1] UChar
…………
nt!_KAPC_STATE
+0x000 ApcListHead : [2] _LIST_ENTRY錛屾瘡涓寚閽堟寚鍚慱KAPC緇撴瀯
+0x010 Process : Ptr32 _KPROCESS
+0x014 KernelApcInProgress : UChar
+0x015 KernelApcPending : UChar
+0x016 UserApcPending : UChar
涓?姣忎釜綰跨▼)鏈変袱涓?APC 闃熷垪銆傝繖鏄洜涓?APC 鍑芥暟鍒嗕負鐢ㄦ埛 APC 鍜屽唴鏍?APC 涓ょ錛屽悇鏈?br>鍚勭殑闃熷垪銆傛墍璋撶敤鎴?APC錛屾槸鎸囩浉搴旂殑 APC 鍑芥暟浣嶄簬鐢ㄦ埛絀洪棿銆佸湪鐢ㄦ埛絀洪棿鎵ц錛涜屽唴鏍?br>APC錛屽垯鐩稿簲鐨?APC 鍑芥暟涓哄唴鏍稿嚱鏁般?/p>
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment,
InsertApcEnvironment
} KAPC_ENVIRONMENT;
nt!_KAPC
+0x000 Type : UChar
+0x001 SpareByte0 : UChar
+0x002 Size : UChar
+0x003 SpareByte1 : UChar
+0x004 SpareLong0 : Uint4B
+0x008 Thread : Ptr32 _KTHREAD
+0x00c ApcListEntry : _LIST_ENTRY
+0x014 KernelRoutine : Ptr32 void
+0x018 RundownRoutine : Ptr32 void
+0x01c NormalRoutine : Ptr32 void
+0x020 NormalContext : Ptr32 Void
+0x024 SystemArgument1 : Ptr32 Void
+0x028 SystemArgument2 : Ptr32 Void
+0x02c ApcStateIndex : Char
+0x02d ApcMode : Char
+0x02e Inserted : UChar
VOID
KeInitializeApc (
__out PRKAPC Apc,
__in PRKTHREAD Thread,
__in KAPC_ENVIRONMENT Environment,
__in PKKERNEL_ROUTINE KernelRoutine,
__in_opt PKRUNDOWN_ROUTINE RundownRoutine,
__in_opt PKNORMAL_ROUTINE NormalRoutine,
__in_opt KPROCESSOR_MODE ProcessorMode,
__in_opt PVOID NormalContext
);
NTKERNELAPI
BOOLEAN
KeInsertQueueApc (
__inout PRKAPC Apc,
__in_opt PVOID SystemArgument1,
__in_opt PVOID SystemArgument2,
__in KPRIORITY Increment
);
DISPATCH_USER_APC ebp, ReturnCurrentEax
; Exit from SystemService
;
local a, b, c
c:
.errnz (EFLAGS_V86_MASK AND 0FF00FFFFh)
jnz short b ; if nz, yes, go check for APC
test byte ptr [TFrame]+TsSegCs,MODE_MASK ; is previous mode user mode?
jz a ; No, previousmode=Kernel, jump out
b: mov ebx, PCR[PcPrcbData+PbCurrentThread]; get addr of current thread
mov byte ptr [ebx]+ThAlerted, 0 ; clear kernel mode alerted
cmp byte ptr [ebx]+ThApcState.AsUserApcPending, 0
je a ; if eq, no user APC pending
ifnb <ReturnCurrentEax>;鏉′歡瀹忔眹緙栵紝濡傛灉ReturnCurrentEax鍙傛暟涓嶄負絀猴紝鍒欑紪璇戯紒
mov [ebx].TsEax, eax ; Store return code in trap frame
mov dword ptr [ebx]+TsSegFs, KGDT_R3_TEB OR RPL_MASK
mov dword ptr [ebx]+TsSegDs, KGDT_R3_DATA OR RPL_MASK
mov dword ptr [ebx]+TsSegEs, KGDT_R3_DATA OR RPL_MASK
mov dword ptr [ebx]+TsSegGs, 0
endif
; Save previous IRQL and set new priority level
;
RaiseIrql APC_LEVEL
push eax ; Save OldIrql
; call the APC delivery routine.
;
; ebx - Trap frame
; 0 - Null exception frame
; 1 - Previous mode
;
; call APC deliver routine
;
LowerIrql ecx
mov eax, [ebx].TsEax ; Restore eax, just in case
endif
jmp b ; 娉ㄦ剰榪欎釜寰幆錛侊紒
a:
endm
鍓嶉潰璁茶繃錛孠THREAD 涓湁涓や釜 KAPC_STATE 鏁版嵁緇撴瀯錛屼竴涓槸 ApcState錛屽彟涓涓槸SavedApcState錛屼簩鑰呴兘鏈堿PC 闃熷垪錛屼絾鏄鎶曢掔殑鍙槸ApcState 涓殑闃熷垪銆?/p>
IN KPROCESSOR_MODE PreviousMode,//鍐欐垚DeliverMode涓嶆槸鏇村ソ
IN PKEXCEPTION_FRAME ExceptionFrame,//榪欎釜鍙傛暟鍑犱箮灝辨槸0
IN PKTRAP_FRAME TrapFrame
)
User APCs run strictly in user mode and only when the current thread is in an alertable wait state. The operating system uses user APCs to implement mechanisms such as overlapped I/O and the QueueUserApc Win32 routine. 錛坮un IRQL = PASSIVE_LEVEL錛?br>Normal kernel APCs run in kernel mode at IRQL = PASSIVE_LEVEL. A normal kernel APC preempts all user-mode code, including user APCs. Normal kernel APCs are generally used by file systems and file-system filter drivers.
Special kernel APCs run in kernel mode at IRQL = APC_LEVEL. A special kernel APC preempts user-mode code and kernel-mode code that executes at IRQL = PASSIVE_LEVEL, including both user APCs and normal kernel APCs. The operating system uses special kernel APCs to handle operations such as I/O request completion.
浠庝唬鐮佺殑瑙掑害鐪嬫槸榪欐牱鐨勶細
_KAPC.ApcMode==UserMode,_KAPC.KernelRoutine!=NULL,_KAPC.NormolRoutine!=NULL
鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛?a >http://blog.csdn.net/better0332/archive/2009/06/29/4306683.aspx
1) APCs鍏佽鐢ㄦ埛紼嬪簭鍜岀郴緇熷厓浠跺湪涓涓繘紼嬬殑鍦板潃絀洪棿鍐呮煇涓嚎紼嬬殑涓婁笅鏂囦腑鎵ц浠g爜銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">2) I/O綆$悊鍣ㄤ嬌鐢ˋPCs鏉ュ畬鎴愪竴涓嚎紼嬪彂璧風殑寮傛鐨処/O鎿嶄綔銆備緥濡傦細褰撲竴涓澶囬┍鍔ㄨ皟鐢↖oCompleteRequest鏉ラ氱煡I/O綆$悊鍣紝瀹冨凡緇忕粨鏉熷鐞嗕竴涓紓姝/O璇鋒眰鏃訛紝I/O綆$悊鍣ㄦ帓闃熶竴涓猘pc鍒板彂璧瘋姹傜殑綰跨▼銆傜劧鍚庣嚎紼嬪湪涓涓緝浣嶪RQL綰у埆錛屾潵鎵цAPC. APC鐨勪綔鐢ㄦ槸浠庣郴緇熺┖闂存嫹璐滻/O鎿嶄綔緇撴灉鍜岀姸鎬佷俊鎭埌綰跨▼铏氭嫙鍐呭瓨絀洪棿鐨勪竴涓紦鍐蹭腑銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">3) 浣跨敤APC鍙互寰楀埌鎴栬呰緗竴涓嚎紼嬬殑涓婁笅鏂囧拰鎸傝搗綰跨▼鐨勬墽琛屻?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
灝界APCs鍦╪t浣撶郴緇撴瀯涓嬭騫挎硾浣跨敤錛屼絾鏄叧浜庢庢牱浣跨敤瀹冪殑鏂囨。鍗撮潪甯哥殑緙轟箯銆傛湰綃囨垜浠緇嗕粙緇嶄笅nt緋葷粺鏄庢牱澶勭悊APCs鐨勶紝騫朵笖璁板綍瀵煎嚭鐨刵t鍑芥暟錛屾柟渚胯澶囬┍鍔ㄥ紑鍙戣呭湪浠栦滑鐨勭▼搴忎腑浣跨敤APCs銆傛垜涔熶細灞曠ず涓涓潪甯稿彲闈犵殑NT鐨凙PC璋冨害瀛愮▼搴廗iDeliverApc鐨勫疄鐜幫紝鏉ュ府鍔╀綘鏇村ソ鐨勬帉鎻PC璋冨害鐨勫唴騫曘?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
APC瀵硅薄
鍦∟T涓紝鏈変袱縐嶇被鍨嬬殑APCs錛氱敤鎴鋒ā寮忓拰鍐呮牳妯″紡銆傜敤鎴稟PCs榪愯鍦ㄧ敤鎴鋒ā寮忎笅鐩爣綰跨▼褰撳墠涓婁笅鏂囦腑錛屽茍涓旈渶瑕佷粠鐩爣綰跨▼寰楀埌璁稿彲鏉ヨ繍琛屻傜壒鍒槸錛岀敤鎴鋒ā寮忕殑APCs闇瑕佺洰鏍囩嚎紼嬪鍦╝lertable絳夊緟鐘舵佹墠鑳借鎴愬姛鐨勮皟搴︽墽琛屻傞氳繃璋冪敤涓嬮潰浠繪剰涓涓嚱鏁幫紝閮藉彲浠ヨ綰跨▼榪涘叆榪欑鐘舵併傝繖浜涘嚱鏁版槸錛欿eWaitForSingleObject, KeWaitForMultipleObjects, KeWaitForMutexObject, KeDelayExecutionThread銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">瀵逛簬鐢ㄦ埛妯″紡涓嬶紝鍙互璋冪敤鍑芥暟SleepEx, SignalObjectAndWait, WaitForSingleObjectEx, WaitForMultipleObjectsEx,MsgWaitForMultipleObjectsEx 閮藉彲浠ヤ嬌鐩爣綰跨▼澶勪簬alertable絳夊緟鐘舵侊紝浠庤岃鐢ㄦ埛妯″紡APCs鎵ц,鍘熷洜鏄繖浜涘嚱鏁版渶緇堥兘鏄皟鐢ㄤ簡鍐呮牳涓殑KeWaitForSingleObject, KeWaitForMultipleObjects, KeWaitForMutexObject, KeDelayExecutionThread絳夊嚱鏁般傚彟澶栭氳繃璋冪敤涓涓湭鍏紑鐨刟lert-test鏈嶅姟KeTestAlertThread錛岀敤鎴風嚎紼嬪彲浠ヤ嬌鐢ㄦ埛妯″紡APCs鎵ц銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
褰撲竴涓敤鎴鋒ā寮廇PC琚姇閫掑埌涓涓嚎紼嬶紝璋冪敤涓婇潰鐨勭瓑寰呭嚱鏁幫紝濡傛灉榪斿洖絳夊緟鐘舵丼TATUS_USER_APC錛屽湪榪斿洖鐢ㄦ埛妯″紡鏃訛紝鍐呮牳杞幓鎺у埗APC渚嬬▼錛屽綋APC渚嬬▼瀹屾垚鍚庯紝鍐嶇戶緇嚎紼嬬殑鎵ц.
鍜岀敤鎴鋒ā寮廇PCs姣旇緝錛屽唴鏍告ā寮廇PCs鎵ц鍦ㄥ唴鏍告ā寮忎笅銆傚彲浠ヨ鍒掑垎涓哄父瑙勭殑鍜岀壒孌婄殑涓ょ被銆傚綋APCs琚姇閫掑埌涓涓壒孌婄殑綰跨▼錛岀壒孌婄殑鍐呮牳妯″紡APCs涓嶉渶瑕佷粠綰跨▼寰楀埌璁稿彲鏉ヨ繍琛屻傜劧鑰岋紝甯歌鐨勫唴鏍告ā寮廇PCs鍦ㄤ粬浠垚鍔熸墽琛屽墠錛岄渶瑕佹湁鐗瑰畾鐨勭幆澧冦傛澶栵紝鐗規畩鐨勫唴鏍窤PC琚敖鍙兘蹇湴鎵ц錛屾棦鍙APC_LEVEL綰т笂鏈夊彲璋冨害鐨勬椿鍔ㄣ傚湪寰堝鎯呭喌涓嬶紝鐗規畩鐨勫唴鏍窤PC鐢氳嚦鑳藉敜閱掗樆濉炵殑綰跨▼銆傛櫘閫氱殑鍐呮牳APC浠呭湪鎵鏈夌壒孌夾PC閮借鎵ц瀹岋紝騫朵笖鐩爣綰跨▼浠嶅湪榪愯錛屽悓鏃惰綰跨▼涓篃娌℃湁鍏跺畠鍐呮牳妯″紡APC姝f墽琛屾椂鎵嶆墽琛屻傜敤鎴鋒ā寮廇PC鍦ㄦ墍鏈夊唴鏍告ā寮廇PC鎵ц瀹屽悗鎵嶆墽琛岋紝騫朵笖浠呭湪鐩爣綰跨▼鏈塧lertable灞炴ф椂鎵嶆墽琛屻?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
姣忎竴涓瓑寰呮墽琛岀殑APC閮藉瓨鍦ㄤ簬涓涓嚎紼嬫墽琛屼綋錛岀敱鍐呮牳綆$悊鐨勯槦鍒椾腑銆傜郴緇熶腑鐨勬瘡涓涓嚎紼嬮兘鍖呭惈涓や釜APC闃熷垪錛屼竴涓槸涓虹敤鎴鋒ā寮廇PCs,鍙︿竴涓槸涓哄唴鏍告ā寮廇PCs鐨勩?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">NT閫氳繃涓涓垚涓篕APC鐨勫唴鏍告帶鍒跺璞℃潵鎻忚堪涓涓肌錛幫跡錛庡敖綆★激錛わ極涓病鏈夋槑紜殑鏂囨。鍖栵肌錛幫跡锝擄紝浣嗘槸鍦∟TDDK.H涓嵈闈炲父娓呮鐨勫畾涔変簡錛★及錛e璞°備粠涓嬮潰鐨凨APC瀵硅薄鐨勫畾涔夌湅錛屾湁浜涙槸涓嶉渶瑕佽鏄庣殑銆傚儚Type鍜孲ize銆俆ype琛ㄧず浜嗚繖鏄竴涓狝PC鍐呮牳瀵硅薄銆傚湪nt涓紝姣忎竴涓唴鏍稿璞℃垨鑰呮墽琛屼綋瀵硅薄閮芥湁Type鍜孲ize榪欎袱涓煙銆傜敱姝ゅ鐞嗗嚱鏁板彲浠ョ‘瀹氬綋鍓嶅鐞嗙殑瀵硅薄銆係ize琛ㄧず涓涓瓧瀵歸綈鐨勭粨鏋勪綋鐨勫ぇ灝忋備篃灝辨槸鎸囨槑浜嗗璞″崰鐨勫唴瀛樼┖闂村ぇ灝忋係pare0鐪嬭搗鏉ユ湁浜涙櫐娑╅毦鎳傦紝浣嗘槸瀹冩槸娌$敤浠涔堜換浣曟繁榪滅殑鎰忎箟錛屼粎浠呮槸涓轟簡鍐呭瓨琛ラ綈銆傚叾浠栫殑鍩熷皢鍦ㄤ笅闈㈢殑綃囧箙涓粙緇嶃?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
//-------------------------------------------------------------------------------------------------------
鍑犱釜鍑芥暟澹版槑鍜岀粨鏋勫畾涔夛細
typedef struct _KAPC {
CSHORT Type;
CSHORT Size;
ULONG Spare0;
struct _KTHREAD *Thread;
LIST_ENTRY ApcListEntry;
PKKERNEL_ROUTINE KernelRoutine;
PKRUNDOWN_ROUTINE RundownRoutine;
PKNORMAL_ROUTINE NormalRoutine;
PVOID NormalContext;
//
// N.B. The following two members MUST be together.
//
PVOID SystemArgument1;
PVOID SystemArgument2;
CCHAR ApcStateIndex;
KPROCESSOR_MODE ApcMode;
BOOLEAN Inserted;
} KAPC, *PKAPC, *RESTRICTED_POINTER PRKAPC;
//------
APC鐜
涓涓嚎紼嬪湪瀹冩墽琛岀殑浠繪剰鏃跺埢錛屽亣璁懼綋鍓嶇殑IRQL鏄湪Passive綰э紝瀹冨彲鑳介渶瑕佷復鏃跺湪鍏朵粬鐨勮繘紼嬩笂涓嬫枃涓墽琛屼唬鐮侊紝涓轟簡瀹屾垚榪欎釜鎿嶄綔錛岀嚎紼嬭皟鐢ㄧ郴緇熷姛鑳藉嚱鏁癒eAttachProcess錛屽湪浠庤繖涓皟鐢ㄨ繑鍥炴椂錛岀嚎紼嬫墽琛屽湪鍙︿竴涓繘紼嬬殑鍦板潃絀洪棿銆傚厛鍓嶆墍鏈夊湪綰跨▼鑷繁鐨勮繘紼嬩笂涓嬫枃涓瓑寰呮墽琛岀殑APCs,鐢變簬榪欐椂鍏舵墍灞炶繘紼嬬殑鍦板潃絀洪棿涓嶆槸褰撳墠鍙敤鐨勶紝鍥犳浠栦滑涓嶈兘琚姇閫掓墽琛屻傜劧鑰岋紝鏂扮殑鎻掑叆鍒拌繖涓嚎紼嬬殑APCs鍙互鎵ц鍦ㄨ繖涓柊鐨勮繘紼嬬┖闂淬傜敋鑷沖綋綰跨▼鏈鍚庝粠鏂扮殑榪涚▼涓垎紱繪椂錛屾柊鐨勬彃鍏ュ埌榪欎釜綰跨▼鐨凙PCs榪樺彲浠ュ湪榪欎釜綰跨▼鎵灞炵殑榪涚▼涓婁笅鏂囦腑鎵ц銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">涓轟簡杈懼埌鎺у埗APC浼犻佺殑榪欎釜紼嬪害錛孨T涓瘡涓嚎紼嬬淮鎶や簡涓や釜APC鐜鎴栬呰鏄姸鎬併傛瘡涓涓狝PC鐜鍖呭惈浜嗙敤鎴鋒ā寮忕殑APC闃熷垪鍜屽唴鏍告ā寮忕殑APC闃熷垪錛屼竴涓寚鍚戝綋鍓嶈繘紼嬪璞$殑鎸囬拡鍜屼笁涓帶鍒跺彉閲忥紝鐢ㄤ簬鎸囧嚭錛氭槸鍚︽湁鏈喅鐨勫唴鏍告ā寮廇PCs(KernelApcPending),鏄惁鏈夊父瑙勫唴鏍告ā寮廇PC鍦ㄨ繘琛屼腑(KernelApcInProgress)錛屾槸鍚︽湁鏈喅鐨勭敤鎴鋒ā寮忕殑APC(UserApcPending). 榪欎簺APC鐨勭幆澧冧繚瀛樺湪綰跨▼瀵硅薄鐨凙pcStatePointer鍩熶腑銆傝繖涓煙鏄敱2涓厓绱犵粍鎴愮殑鏁扮粍銆傚嵆錛?0x138 ApcStatePointer : [2] Ptr32 _KAPC_STATE
typedef struct _KAPC_STATE {
LIST_ENTRY ApcListHead[MaximumMode];
struct _KPROCESS *Process;
BOOLEAN KernelApcInProgress;
BOOLEAN KernelApcPending;
BOOLEAN UserApcPending;
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;
lkd> dt _kthread
ntdll!_KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY
+0x018 InitialStack : Ptr32 Void
+0x01c StackLimit : Ptr32 Void
+0x020 Teb : Ptr32 Void
+0x024 TlsArray : Ptr32 Void
+0x028 KernelStack : Ptr32 Void
+0x02c DebugActive : UChar
+0x02d State : UChar
+0x02e Alerted : [2] UChar
+0x030 Iopl : UChar
+0x031 NpxState : UChar
+0x032 Saturation : Char
+0x033 Priority : Char
+0x034 ApcState : _KAPC_STATE
+0x04c ContextSwitches : Uint4B
+0x050 IdleSwapBlock : UChar
+0x051 Spare0 : [3] UChar
+0x054 WaitStatus : Int4B
+0x058 WaitIrql : UChar
+0x059 WaitMode : Char
+0x05a WaitNext : UChar
+0x05b WaitReason : UChar
+0x05c WaitBlockList : Ptr32 _KWAIT_BLOCK
+0x060 WaitListEntry : _LIST_ENTRY
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 WaitTime : Uint4B
+0x06c BasePriority : Char
+0x06d DecrementCount : UChar
+0x06e PriorityDecrement : Char
+0x06f Quantum : Char
+0x070 WaitBlock : [4] _KWAIT_BLOCK
+0x0d0 LegoData : Ptr32 Void
+0x0d4 KernelApcDisable : Uint4B
+0x0d8 UserAffinity : Uint4B
+0x0dc SystemAffinityActive : UChar
+0x0dd PowerState : UChar
+0x0de NpxIrql : UChar
+0x0df InitialNode : UChar
+0x0e0 ServiceTable : Ptr32 Void
+0x0e4 Queue : Ptr32 _KQUEUE
+0x0e8 ApcQueueLock : Uint4B
+0x0f0 Timer : _KTIMER
+0x118 QueueListEntry : _LIST_ENTRY
+0x120 SoftAffinity : Uint4B
+0x124 Affinity : Uint4B
+0x128 Preempted : UChar
+0x129 ProcessReadyQueue : UChar
+0x12a KernelStackResident : UChar
+0x12b NextProcessor : UChar
+0x12c CallbackStack : Ptr32 Void
+0x130 Win32Thread : Ptr32 Void
+0x134 TrapFrame : Ptr32 _KTRAP_FRAME
+0x138 ApcStatePointer : [2] Ptr32 _KAPC_STATE
+0x140 PreviousMode : Char
+0x141 EnableStackSwap : UChar
+0x142 LargeStack : UChar
+0x143 ResourceIndex : UChar
+0x144 KernelTime : Uint4B
+0x148 UserTime : Uint4B
+0x14c SavedApcState : _KAPC_STATE
+0x164 Alertable : UChar
+0x165 ApcStateIndex : UChar
+0x166 ApcQueueable : UChar
+0x167 AutoAlignment : UChar
+0x168 StackBase : Ptr32 Void
+0x16c SuspendApc : _KAPC
+0x19c SuspendSemaphore : _KSEMAPHORE
+0x1b0 ThreadListEntry : _LIST_ENTRY
+0x1b8 FreezeCount : Char
+0x1b9 SuspendCount : Char
+0x1ba IdealProcessor : UChar
+0x1bb DisableBoost : UChar
涓籄PC鐜鏄綅浜庣嚎紼嬪璞$殑ApcState 鍩燂紝鍗籌細
+0x034 ApcState : _KAPC_STATE
綰跨▼涓瓑寰呭湪褰撳墠榪涚▼涓婁笅鏂囦腑鎵ц鐨凙PC淇濆瓨鍦ˋpcState鐨勯槦鍒椾腑銆傛棤璁轟綍鏃訛紝NT鐨凙PC媧懼彂鍣?dispatcher)鍜屽叾浠栫郴緇熷厓浠舵煡璇竴涓嚎紼嬫湭鍐崇殑APCs鏃? 浠栦滑閮戒細媯鏌ヤ富APC鐜錛屽鏋滆繖閲屾湁浠諱綍鏈喅鐨凙PCs,灝變細椹笂琚姇閫掞紝鎴栬呬慨鏀瑰畠鐨勬帶鍒跺彉閲忕◢鍚庢姇閫掋?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
絎簩涓狝PC鐜鏄綅浜庣嚎紼嬪璞$殑SavedApcState鍩燂紝褰撶嚎紼嬩復鏃舵寕鎺ュ埌鍏朵粬榪涚▼鏃訛紝瀹冩槸鐢ㄦ潵澶囦喚涓籄PC鐜鐨勩?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
褰撲竴涓嚎紼嬭皟鐢↘eAttachProcess錛屽湪鍙﹀鐨勮繘紼嬩笂涓嬫枃涓墽琛屽悗緇殑浠g爜鏃訛紝ApcState鍩熺殑鍐呭灝辮鎷瘋礉鍒癝avedApcState鍩熴傜劧鍚嶢pcState鍩熻娓呯┖錛屽畠鐨凙PC闃熷垪閲嶆柊鍒濆鍖栵紝鎺у埗鍙橀噺璁劇疆涓?錛屽綋鍓嶈繘紼嬪煙璁劇疆涓烘柊鐨勮繘紼嬨傝繖浜涙楠ゆ垚鍔熺殑紜繚鍏堝墠鍦ㄧ嚎紼嬫墍灞炵殑榪涚▼涓婁笅鏂囧湴鍧絀洪棿涓瓑寰呯殑APCs錛屽綋綰跨▼榪愯鍦ㄥ叾瀹冧笉鍚岀殑榪涚▼涓婁笅鏂囨椂錛岃繖浜汚PCs涓嶈浼犻佹墽琛屻傞殢鍚庯紝ApcStatePointer鍩熸暟緇勫唴瀹硅鏇存柊鏉ュ弽鏄犳柊鐨勭姸鎬侊紝鏁扮粍涓涓涓厓绱犳寚鍚慡avedApcState鍩燂紝絎簩涓厓绱犳寚鍚慉pcState鍩燂紝琛ㄦ槑綰跨▼鎵灞炶繘紼嬩笂涓嬫枃鐨凙PC鐜浣嶄簬SavedApcState鍩熴傜嚎紼嬬殑鏂扮殑榪涚▼涓婁笅鏂囩殑APC鐜浣嶄簬ApcState鍩熴傛渶鍚庯紝褰撳墠榪涚▼涓婁笅鏂囧垏鎹㈠埌鏂扮殑榪涚▼涓婁笅鏂囥?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
瀵逛簬涓涓狝PC瀵硅薄錛屽喅瀹氬綋鍓岮PC鐜鐨勬槸ApcStateIndex鍩熴侫pcStateIndex鍩熺殑鍊間綔涓篈pcStatePointer鍩熸暟緇勭殑绱㈠紩鏉ュ緱鍒扮洰鏍嘇PC鐜鎸囬拡銆傞殢鍚庯紝鐩爣APC鐜鎸囬拡鐢ㄦ潵鍦ㄧ浉搴旂殑闃熷垪涓瓨鏀綼pc瀵硅薄.
褰撶嚎紼嬩粠鏂扮殑榪涚▼涓劚紱繪椂(KeDetachProcess), 浠諱綍鍦ㄦ柊鐨勮繘紼嬪湴鍧絀洪棿涓瓑寰呮墽琛岀殑鏈喅鐨勫唴鏍窤PCs琚淳鍙戞墽琛屻傞殢鍚嶴avedApcState 鍩熺殑鍐呭琚嫹璐濆洖ApcState鍩熴係avedApcState 鍩熺殑鍐呭琚竻絀猴紝綰跨▼鐨凙pcStateIndex鍩熻璁句負OriginalApcEnvironment錛孉pcStatePointer鍩熸洿鏂幫紝褰撳墠榪涚▼涓婁笅鏂囧垏鎹㈠埌綰跨▼鎵灞炶繘紼嬨?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
浣跨敤APCs
璁懼椹卞姩紼嬪簭浣跨敤涓や釜涓昏鍑芥暟鏉ュ埄鐢ˋPCs, 絎竴涓槸KeInitializeApc錛岀敤鏉ュ垵濮嬪寲APC瀵硅薄銆傝繖涓嚱鏁版帴鍙椾竴涓┍鍔ㄥ垎閰嶇殑APC瀵硅薄錛屼竴涓洰鏍囩嚎紼嬪璞℃寚閽堬紝APC鐜绱㈠紩錛堟寚鍑篈PC瀵硅薄瀛樻斁浜庡摢涓狝PC鐜錛夛紝APC鐨刱ernel,rundown鍜宯ormal渚嬬▼鎸囬拡錛孉PC綾誨瀷錛堢敤鎴鋒ā寮忔垨鑰呭唴鏍告ā寮忥級鍜屼竴涓笂涓嬫枃鍙傛暟銆?鍑芥暟澹版槑濡備笅錛?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
NTKERNELAPI
VOID
KeInitializeApc (
IN PRKAPC Apc,
IN PKTHREAD Thread,
IN KAPC_ENVIRONMENT Environment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL,
IN KPROCESSOR_MODE ApcMode,
IN PVOID NormalContext
);
typedef enum _KAPC_ENVIRONMENT {
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment
} KAPC_ENVIRONMENT;
KeInitializeApc 棣栧厛璁劇疆APC瀵硅薄鐨凾ype鍜孲ize鍩熶竴涓傚綋鐨勫鹼紝鐒跺悗媯鏌ュ弬鏁癊nvironment鐨勫鹼紝濡傛灉鏄疌urrentApcEnvironment錛岄偅涔圓pcStateIndex鍩熻緗負鐩爣綰跨▼鐨凙pcStateIndex鍩熴傚惁鍒欙紝ApcStateIndex鍩熻緗負鍙傛暟Environment鐨勫箋傞殢鍚庯紝鍑芥暟鐩存帴鐢ㄥ弬鏁拌緗瓵PC瀵硅薄Thread錛孯undownRoutine錛孠ernelRoutine鍩熺殑鍊箋備負浜嗘紜湴紜畾APC鐨勭被鍨嬶紝KeInitializeApc 媯鏌ュ弬鏁癗ormalRoutine鐨勫鹼紝濡傛灉鏄疦ULL錛孉pcMode鍩熺殑鍊艱緗負KernelMode錛孨ormalContext鍩熻緗負NULL銆傚鏋淣ormalRoutine鐨勫間笉鏄疦ULL錛岃繖鏃跺欏畠涓瀹氭寚鍚戜竴涓湁鏁堢殑渚嬬▼錛屽氨鐢ㄧ浉搴旂殑鍙傛暟鏉ヨ緗瓵pcMode鍩熷拰NormalContext鍩熴傛渶鍚庯紝KeInitializeApc 璁劇疆Inserted鍩熶負FALSE.鐒惰屽垵濮嬪寲APC瀵硅薄錛屽茍娌℃湁鎶婂畠瀛樻斁鍒扮浉搴旂殑APC闃熷垪涓?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
浠庤繖涓В閲婄湅錛屼綘鍙互浜嗚В鍒癆PCs瀵硅薄濡傛灉緙哄皯鏈夋晥鐨凬ormalRoutine錛屽氨浼氳褰撲綔鍐呮牳妯″紡APCs.灝ゅ叾鏄畠浠細琚涓烘槸鐗規畩鐨勫唴鏍告ā寮廇PCs.
瀹為檯涓婏紝I/O綆$悊鍣ㄥ氨鏄敤榪欑被鐨凙PC鏉ュ畬鎴愬紓姝/O鎿嶄綔銆傜浉鍙嶅湴錛孉PC瀵硅薄瀹氫箟浜嗘湁鏁堢殑NormalRoutine錛屽茍涓擜pcMode鍩熸槸KernelMode錛屽氨浼氳褰撲綔甯歌鐨勫唴鏍告ā寮廇PCs,鍚﹀垯灝變細琚綋浣滄槸鐢ㄦ埛妯″紡APCs. NTDDK.H涓璌ernelRoutine, RundownRoutine, and NormalRoutine 鐨勫畾涔夊涓嬶細
typedef
VOID
(*PKKERNEL_ROUTINE) (
IN struct _KAPC *Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2
);
typedef
VOID
(*PKRUNDOWN_ROUTINE) (
IN struct _KAPC *Apc
);
typedef
VOID
(*PKNORMAL_ROUTINE) (
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
//------------------
閫氬父錛屾棤璁烘槸浠涔堢被鍨嬶紝姣忎釜APC瀵硅薄蹇呴』瑕佸寘鍚竴涓湁鏁堢殑KernelRoutine 鍑芥暟鎸囬拡銆傚綋榪欎釜APC琚玁T鐨凙PC dispatcher浼犻佹墽琛屾椂錛岃繖涓緥紼嬮鍏堣鎵ц銆傜敤鎴鋒ā寮忕殑APCs蹇呴』鍖呭惈涓涓湁鏁堢殑NormalRoutine 鍑芥暟鎸囬拡錛岃繖涓嚱鏁板繀欏誨湪鐢ㄦ埛鍐呭瓨鍖哄煙銆傚悓鏍風殑錛屽父瑙勫唴鏍告ā寮廇PCs涔熷繀欏誨寘鍚竴涓湁鏁堢殑NormalRoutine錛屼絾鏄畠灝卞儚KernelRoutine涓鏍瘋繍琛屽湪鍐呮牳妯″紡銆備綔涓哄彲閫夋嫨鐨勶紝浠繪剰綾誨瀷鐨凙PC閮藉彲浠ュ畾涔変竴涓湁鏁堢殑RundownRoutine錛岃繖涓緥紼嬪繀欏誨湪鍐呮牳鍐呭瓨鍖哄煙錛屽茍涓斾粎浠呭綋緋葷粺闇瑕侀噴鏀続PC闃熷垪鐨勫唴瀹規椂錛屾墠琚皟鐢ㄣ備緥濡傜嚎紼嬮鍑烘椂錛屽湪榪欑鎯呭喌涓嬶紝KernelRoutine鍜孨ormalRoutine閮戒笉鎵ц錛屽彧鏈塕undownRoutine鎵ц銆傛病鏈夎繖涓緥紼嬬殑APC瀵硅薄浼氳鍒犻櫎銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
璁頒綇錛屾姇閫扐PCs鍒頒竴涓嚎紼嬬殑鍔ㄤ綔錛屼粎浠呮槸鎿嶄綔緋葷粺璋冪敤KiDeliverApc瀹屾垚鐨勩傛墽琛孉PC瀹為檯涓婂氨鏄皟鐢ˋPC鍐呯殑渚嬬▼銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
涓鏃PC瀵硅薄瀹屾垚鍒濆鍖栧悗錛岃澶囬┍鍔ㄨ皟鐢↘eInsertQueueApc鏉ュ皢APC瀵硅薄瀛樻斁鍒扮洰鏍囩嚎紼嬬殑鐩稿簲鐨凙PC闃熷垪涓傝繖涓嚱鏁版帴鍙椾竴涓敱KeInitializeApc瀹屾垚鍒濆鍖栫殑APC瀵硅薄鎸囬拡錛屼袱涓郴緇熷弬鏁板拰涓涓紭鍏堢駭澧為噺銆傝窡浼犻掔粰KeInitializeApc鍑芥暟鐨勫弬鏁癱ontext 涓鏍鳳紝榪欎袱涓郴緇熷弬鏁板彧鏄湪APC鐨勪緥紼嬫墽琛屾椂錛岀畝鍗曠殑浼犻掔粰APC鐨勪緥紼嬨?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
NTKERNELAPI
BOOLEAN
KeInsertQueueApc (
IN PRKAPC Apc,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2,
IN KPRIORITY Increment
);
//-----------------
鍦↘eInsertQueueApc 灝咥PC瀵硅薄瀛樻斁鍒扮洰鏍囩嚎紼嬬浉搴旂殑APC闃熷垪涔嬪墠錛屽畠棣栧厛媯鏌ョ洰鏍囩嚎紼嬫槸鍚︽槸APC queueable銆傚鏋滀笉鏄紝鍑芥暟绔嬪嵆榪斿洖FALSE.濡傛灉鏄紝鍑芥暟鐩存帴鐢ㄥ弬鏁拌緗甋ystemArgument1鍩熷拰SystemArgument2 鍩燂紝闅忓悗錛屽嚱鏁拌皟鐢↘iInsertQueueApc鏉ュ皢APC瀵硅薄瀛樻斁鍒扮浉搴旂殑APC闃熷垪銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
KiInsertQueueApc 浠呬粎鎺ュ彈涓涓狝PC瀵硅薄鍜屼竴涓紭鍏堢駭澧為噺銆傝繖涓嚱鏁伴鍏堝緱鍒扮嚎紼婣PC闃熷垪鐨剆pinlock騫朵笖鎸佹湁瀹冿紝闃叉鍏朵粬綰跨▼淇敼褰撳墠綰跨▼鐨凙PC緇撴瀯銆傞殢鍚庯紝媯鏌PC瀵硅薄鐨処nserted 鍩熴傚鏋滄槸TRUE,琛ㄦ槑榪欎釜APC瀵硅薄宸茬粡瀛樻斁鍒癆PC闃熷垪涓簡錛屽嚱鏁扮珛鍗寵繑鍥濬ALSE.濡傛灉APC瀵硅薄鐨処nserted 鍩熸槸FALSE.鍑芥暟閫氳繃ApcStateIndex鍩熸潵紜畾鐩爣APC鐜錛岀劧鍚庢妸APC瀵硅薄瀛樻斁鍒扮浉搴旂殑APC闃熷垪涓紝鍗沖皢APC瀵硅薄涓殑ApcListEntry 鍩熼摼鍏ュ埌APC鐜鐨凙pcListHead鍩熶腑銆傞摼鍏ョ殑浣嶇疆鐢盇PC鐨勭被鍨嬪喅瀹氥傚父瑙勭殑鍐呮牳妯″紡APC,鐢ㄦ埛妯″紡APC閮芥槸瀛樻斁鍒扮浉搴旂殑APC闃熷垪鐨勬湯绔傜浉鍙嶇殑錛屽鏋滈槦鍒椾腑宸茬粡瀛樻斁浜嗕竴浜汚PC瀵硅薄錛岀壒孌婄殑鍐呮牳妯″紡APC瀛樻斁鍒伴槦鍒椾腑絎竴涓父瑙勫唴鏍告ā寮廇PC瀵硅薄鐨勫墠闈€傚鏋滄槸鍐呮牳瀹氫箟鐨勪竴涓綋綰跨▼閫鍑烘椂浣跨敤鐨勭敤鎴稟PC,瀹冧篃浼氳鏀懼湪鐩稿簲鐨勯槦鍒楃殑鍓嶉潰銆傜劧鍚庯紝綰跨▼鐨勪富APC鐜涓殑UserApcPending鍩熸澂璁劇疆涓篢RUE銆傝繖鏃禟iInsertQueueApc 璁劇疆APC瀵硅薄鐨処nserted 鍩熶負TRUE錛岃〃鏄庤繖涓狝PC瀵硅薄宸茬粡瀛樻斁鍒癆PC闃熷垪涓簡銆傛帴涓嬫潵錛屾鏌ヨ繖涓狝PC瀵硅薄鏄惁琚帓闃熷埌綰跨▼鐨勫綋鍓嶈繘紼嬩笂涓嬫枃APC鐜涓紝濡傛灉涓嶆槸錛屽嚱鏁扮珛鍗寵繑鍥濼RUE銆傚鏋滆繖鏄竴涓唴鏍告ā寮廇PC錛岀嚎紼嬩富APC鐜涓殑KernelApcPending鍩熻緗負TRUE銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
鍦╓IN32 SDK鏂囨。涓槸榪欐牱鎻忚堪APCs鐨勶細 褰撲竴涓狝PC琚垚鍔熺殑瀛樻斁鍒板畠鐨勯槦鍒楀悗錛屽彂鍑轟竴涓蔣涓柇錛孉PC灝嗕細鍦ㄧ嚎紼嬭璋冨害榪愯鐨勪笅涓涓椂闂寸墖鎵ц銆傜劧鑰岃繖涓嶆槸瀹屽叏姝g‘鐨勩傝繖鏍蜂竴涓蔣涓柇錛屼粎浠呮槸褰撲竴涓唴鏍告ā寮忕殑APC錛堟棤璁烘槸甯歌鐨勫唴鏍告ā寮廇PC榪樻槸鐗規畩鐨勫唴鏍告ā寮廇PC錛夐拡瀵逛簬璋冪敤綰跨▼鏃訛紝鎵嶄細鍙戝嚭銆傞殢鍚庡嚱鏁拌繑鍥濼RUE銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
1錛夊鏋淎PC涓嶆槸閽堝浜庤皟鐢ㄧ嚎紼嬶紝鐩爣綰跨▼鍦≒assive鏉冮檺絳夌駭澶勫湪絳夊緟鐘舵侊紱
2錛夎繖鏄竴涓父瑙勫唴鏍告ā寮廇PC
3錛夎繖涓嚎紼嬩笉鍐嶄復鐣屽尯
4錛夋病鏈夊叾浠栫殑甯歌鍐呮牳妯″紡APC浠嶇劧鍦ㄨ繘琛屼腑
閭d箞榪欎釜綰跨▼琚敜閱掞紝榪斿洖鐘舵佹槸STATUS_KERNEL_APC銆備絾鏄瓑寰呯姸鎬佹病鏈塧borted銆?濡傛灉榪欐槸涓涓敤鎴鋒ā寮廇PC錛孠iInsertQueueApc媯鏌ュ垽鏂洰鏍囩嚎紼嬫槸鍚︽槸alertable絳夊緟鐘舵侊紝騫朵笖WaitMode鍩熺瓑浜嶶serMode銆傚鏋滄槸錛屼富APC鐜鐨刄serApcPending 鍩熻緗負TRUE銆傜瓑寰呯姸鎬佽繑鍥濻TATUS_USER_APC錛屾渶鍚庯紝鍑芥暟閲婃斁spinlock錛岃繑鍥濼RUE錛岃〃紺篈PC瀵硅薄宸茬粡琚垚鍔熸斁鍏ラ槦鍒椼?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">鏃╂湡浣滀負APC綆$悊鍑芥暟鐨勮ˉ鍏咃紝璁懼椹卞姩寮鍙戣呭彲浠ヤ嬌鐢ㄦ湭鍏紑鐨勭郴緇熸湇鍔tQueueApcThread鏉ョ洿鎺ュ皢涓涓敤鎴鋒ā寮忕殑APC鎶曢掑埌鏌愪釜綰跨▼銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">榪欎釜鍑芥暟鍐呴儴瀹為檯涓婃槸璋冪敤浜咾eInitializeApc 鍜孠eInsertQueueApc 鏉ュ畬鎴愯繖涓換鍔°?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
NTSYSAPI
NTSTATUS
NTAPI
NtQueueApcThread (
IN HANDLE Thread,
IN PKNORMAL_ROUTINE NormalRoutine,
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
NT鐨凙PC媧懼彂鍣?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
NT媯鏌ユ槸鍚︾嚎紼嬫湁鏈喅鐨凙PCs. 鐒跺悗APC媧懼彂鍣ㄥ瓙紼嬪簭KiDeliverApc鍦ㄨ繖涓嚎紼嬩笂涓嬫枃鎵ц鏉ュ紑濮嬪皢鏈喅鐨凙PC鎵ц銆傛敞鎰忥紝榪欎釜琛屼負涓柇浜嗙嚎紼嬬殑姝e父鎵ц嫻佺▼錛岄鍏堝皢鎺у埗鏉冪粰APC媧懼彂鍣紝闅忓悗褰揔iDeliverApc瀹屾垚鍚庯紝緇х畫綰跨▼鐨勬墽琛屻?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">渚嬪錛氬綋涓涓嚎紼嬭璋冨害榪愯鏃訛紝鏈鍚庝竴姝ワ紝涓婁笅鏂囧垏鎹㈠嚱鏁?SwapContext 鐢ㄦ潵媯鏌ユ槸鍚︽柊鐨勭嚎紼嬫湁鏈喅鐨勫唴鏍窤PCs.濡傛灉鏄紝SwapContext瑕佷箞錛?錛夎姹備竴涓狝PC綰у埆鐨勮蔣涓柇鏉ュ紑濮婣PC鎵ц錛岀敱浜庢柊綰跨▼榪愯鍦ㄤ綆鐨処RQL錛圥assive綰у埆銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">鎴栬咃紙2錛夎繑鍥濼RUE錛岃〃紺烘柊鐨勭嚎紼嬫湁鏈喅鐨勫唴鏍窤PCs銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
絀剁珶鏄墽琛?1)榪樻槸(2)鍙栧喅浜庢柊綰跨▼鎵澶勭殑IRQL綰у埆. 濡傛灉瀹冪殑鏉冮檺綰у埆楂樹簬Passive綰?SwapContext 鎵ц(1),濡傛灉瀹冩槸鍦≒assive綰?鍒欓夋嫨鎵ц(2).
SwapContext鐨勮繑鍥炲間粎浠呮槸鐗瑰畾緋葷粺鍑芥暟鍙敤鐨?榪欎簺緋葷粺鍑芥暟璋冪敤SwapContext鏉ュ己鍒跺垏鎹㈢嚎紼嬩笂涓嬫枃鍒板彟涓涓嚎紼? 鐒跺悗,褰撹繖浜涚郴緇熷嚱鏁扮粡榪囦竴孌墊椂闂村啀緇х畫鏃?浠栦滑閫氬父媯鏌wapContext 鐨勮繑鍥炲?濡傛灉鏄疶RUE,浠栦滑灝變細璋冪敤APC媧懼彂鍣ㄦ潵鎶曢掑唴鏍窤PCs鍒板綋鍓嶇殑綰跨▼. 渚嬪:
緋葷粺鍑芥暟KiSwapThread琚瓑寰呮湇鍔$敤鏉ユ斁寮冨鐞嗗櫒錛岀洿鍒扮瓑寰呯粨鏉熴傝繖涓嚱鏁板唴閮ㄨ皟鐢⊿wapContext銆傚綋絳夊緟緇撴潫錛岀戶緇粠璋冪敤SwapContext澶勬墽琛屾椂錛屽氨浼氭鏌wapContext鐨勮繑鍥炲箋傚鏋滄槸TRUE錛孠iSwapThread浼氶檷浣嶪RQL綰у埆鍒癆PC綰э紝鐒跺悗璋冪敤KiDeliverApc鏉ュ湪褰撳墠綰跨▼鎵ц鍐呮牳APCs.
瀵逛簬鐢ㄦ埛APCs, 鍐呮牳璋冪敤APC媧懼彂鍣ㄤ粎浠呮槸褰撶嚎紼嬪洖鍒扮敤鎴鋒ā寮忥紝騫朵笖綰跨▼鐨勪富APC鐜鐨刄serApcPending鍩熶負TRUE鏃躲備緥濡傦細褰撶郴緇熸湇鍔℃淳鍙戝櫒KiSystemService瀹屾垚涓涓郴緇熸湇鍔¤姹傛鎵撶畻鍥炲埌鐢ㄦ埛妯″紡鏃訛紝瀹冧細媯鏌ユ槸鍚︽湁鏈喅鐨勭敤鎴稟PCs銆傚湪鎵ц涓婏紝KiDeliverApc璋冪敤鐢ㄦ埛APC鐨凨ernelRoutine. 闅忓悗錛孠iInitializeUserApc鍑芥暟琚皟鐢紝鐢ㄦ潵璁劇疆綰跨▼鐨勯櫡闃卞撫銆傛墍浠ヤ粠鍐呮牳妯″紡閫鍑烘椂錛岀嚎紼嬪紑濮嬪湪鐢ㄦ埛妯″紡涓嬫墽琛?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">銆侹iInitializeUserApc鐨勫嚱鏁扮殑浣滅敤鏄嫹璐濆綋鍓嶇嚎紼嬪厛鍓嶇殑鎵ц鐘舵侊紙褰撹繘鍏ュ唴鏍告ā寮忔椂錛岃繖涓姸鎬佷繚瀛樺湪綰跨▼鍐呮牳鏍堝垱寤虹殑闄烽槺甯ч噷錛夛紝浠庡唴鏍告爤鍒扮嚎紼嬬殑鐢ㄦ埛妯″紡鏍堬紝鍒濆鍖栫敤鎴鋒ā寮廇PC銆侫PC媧懼彂鍣ㄥ瓙紼嬪簭KiUserApcDispatcher鍦∟tdll.dll鍐呫傛渶鍚庯紝鍔犺澆闄烽槺甯х殑EIP瀵勫瓨鍣ㄥ拰Ntdll.dll涓璌iUserApcDispatcher鐨勫湴鍧銆傚綋闄烽槺甯ф渶鍚庨噴鏀炬椂錛屽唴鏍稿皢鎺у埗杞氦緇橩iUserApcDispatcher錛岃繖涓嚱鏁拌皟鐢ˋPC鐨凬ormalRoutine渚嬬▼錛孨ormalRoutine鍑芥暟鍦板潃浠ュ強鍙傛暟閮藉湪鏍堜腑錛屽綋渚嬬▼瀹屾垚鏃訛紝瀹冭皟鐢∟tContinue鏉ヨ綰跨▼鍒╃敤鍦ㄦ爤涓厛鍓嶇殑涓婁笅鏂囩戶緇墽琛岋紝浠夸經浠涔堜簨鎯呬篃娌℃湁鍙戠敓榪囥?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
褰撳唴鏍歌皟鐢↘iDeliverApc鏉ユ墽琛屼竴涓敤鎴鋒ā寮廇PC鏃訛紝綰跨▼涓殑PreviousMode鍩熻璁句負UserMode. TrapFrame鍩熸寚鍚戠嚎紼嬬殑闄烽槺甯с傚綋鍐呮牳璋冪敤KiDeliverApc鏉ユ墽琛屽唴鏍窤PCs鏃訛紝綰跨▼涓殑PreviousMode鍩熻璁句負KernelMode. TrapFrame鍩熸寚鍚慛ULL銆?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">娉ㄦ剰錛屾棤璁轟綍鏃跺彧瑕並ernelRoutine琚皟鐢紝浼犻掔粰瀹冪殑鎸囬拡鏄竴涓眬閮ㄧ殑APC灞炴х殑鍓湰錛岀敱浜嶢PC瀵硅薄宸茬粡鑴辯浜嗛槦鍒楋紝鎵浠ュ彲浠ュ畨鍏ㄧ殑鍦↘ernelRoutine涓噴鏀続PC鍐呭瓨銆傛澶栵紝榪欎釜渚嬬▼鍦ㄥ畠鐨勫弬鏁拌浼犻掔粰鍏朵粬渚嬬▼涔嬪墠錛屾湁涓涓渶鍚庣殑鏈轟細鏉ヤ慨鏀硅繖浜涘弬鏁般?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">
緇撹錛?br style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; PADDING-TOP: 0px">APC鎻愪緵浜嗕竴涓潪甯告湁鐢ㄧ殑鏈哄埗錛屽厑璁稿湪鐗瑰畾鐨勭嚎紼嬩笂涓嬫枃涓紓姝ョ殑鎵ц浠g爜銆備綔涓轟竴涓澶囬┍鍔ㄥ紑鍙戣咃紝浣犲彲浠ヤ緷璧朅PCs鍦ㄦ煇涓壒瀹氱殑綰跨▼涓婁笅鏂囦腑鎵ц涓涓緥紼嬶紝鑰屼笉闇瑕佺嚎紼嬬殑璁稿彲鍜屽共娑夈傚浜庣敤鎴峰簲鐢ㄧ▼搴忥紝鐢ㄦ埛妯″紡APCs鍙互鐢ㄦ潵鏈夋晥鍦板疄鐜頒竴浜涘洖璋冮氱煡鏈哄埗銆?/span>
鍦╓indows VISTA鐗堟湰涔嬪悗錛孴DI灝變笉鍐嶄嬌鐢ㄤ簡錛屽彇鑰屼唬涔嬬殑鏄疻indows filter platform鍜學insock kernel銆?br>
NDIS錛孨etwork Driver Interface Specification錛岀綉緇滈┍鍔ㄧ▼搴忔帴鍙h鑼冿紝鍦ㄦ搷浣滅郴緇熶腑鐨勪綅緗?br>\Windows\System32\Drivers\NDIS.sys
褰撲竴涓崗璁┍鍔ㄧ▼搴忔兂瑕佹寜鐓у叾鍗忚鐨勬牸寮忚В鏋愮綉涓婅鍐欑殑鏁版嵁鏃訛紝鑰岃繖浜涙暟鎹繀欏婚氳繃緗戠粶閫傞厤鍣ㄦ墠鑳藉彇寰楋紝鏈熸湜鍗忚椹卞姩紼嬪簭鑳藉鐞嗚В甯傚満涓婄殑姣忎竴嬈劇綉緇滈傞厤鍣ㄧ殑緇嗗井鍖哄埆鏄笉鍙兘鐨勩傛墍浠ュ湪1989騫達紝鐢盡icrosoft鍜?Com鑱斿悎寮鍙戠殑浜哊DIS錛屼嬌寰楀崗璁┍鍔ㄧ▼搴忓彲浠ヤ互涓縐嶄笌璁懼鏃犲叧鐨勬柟寮忔潵璺熺綉緇滈傞厤鍣ㄩ┍鍔ㄧ▼搴忚繘琛岄氫俊銆傞伒浠嶯DIS鐨勭綉緇滈傞厤鍣ㄩ┍鍔ㄧ▼搴忕О涓篘DIS minport driver銆?/span>
NDIS瑙勮寖瀹炵幇浜嗕笌TDI鏍囧噯綾諱技鐨勫姛鑳斤紝閮芥槸灝嗗鏉傜殑涓嬪眰璋冪敤瑙勮寖鍖栥佹爣鍑嗗寲錛屽ぇ澶ф彁楂樹簡Windows鎿嶄綔緋葷粺鐨勫彲鎵╁睍鎬у拰鍏煎鎬с備篃琛ㄧ幇鍦ㄤ袱涓柟闈細
飦?nbsp; 瀵逛簬涓嬪眰錛岃緗戠粶閫傞厤鍣ㄥ埗閫犲晢寰坋asy鐨勫紑鍙戣嚜宸辯殑璁懼椹卞姩紼嬪簭錛屼篃灝辨槸Ndis miniport driver銆傝繖浜沵iniport driver鐩存帴鍒╃敤NDIS鎻愪緵鐨勬帴鍙e彂閫佹寚浠わ紝NDIS瀵硅繖浜涙牸寮忓寲鐨勬寚浠よ繘琛岃В鏋愶紝鍋氳繘涓姝ュ鐞嗐傦紙榪欎簺澶勭悊灝卞埌浜咹AL浜嗭級
飦?nbsp; 瀵逛簬涓婂眰錛屽涓崗璁┍鍔ㄧ▼搴忎笌涓嬪眰minport driver涔嬮棿鐨勯氫俊錛屼篃閮芥槸閫氳繃緇熶竴鐨凬DIS鎺ュ彛錛孨idsAllocatePacket錛孨disSend絳夊嚱鏁版潵鏀跺彂鏁版嵁銆?br>
搴熻瘽涓ゅ彞錛歍DI鍜孨DIS涓ゅぇ鎺ュ彛瑙勮寖錛屾湁鍔涚殑鎻愬崌浜哤indows鎿嶄綔緋葷粺瀵逛笉鍚岃澶囧巶鍟嗙殑鏀寔錛岄檷浣庝簡璁懼鍘傚晢瀵硅澶囬┍鍔ㄧ▼搴忓紑鍙戠殑闅懼害錛涗篃澧炲姞浜嗗浜庝笉鍚岀綉緇滃崗璁殑鏀寔錛岀粰鐢ㄦ埛鏇村己澶х殑緗戠粶鍔熻兘鏀寔銆傝繖縐嶈璁℃垜浠篃鍙互鍦╓indows瀛樺偍綆$悊涓湅鍒幫紝浠庝腑鎴戜滑浼間箮鍙互浜嗚В鍒頒竴浜涳紝Windows鎿嶄綔緋葷粺鍦ㄥ晢涓氫笂鍙栧緱鎴愬姛鐨勫師鍥犮侺inux鎿嶄綔緋葷粺涓病鏈夎繖鏍風殑椹卞姩灞傛緇撴瀯銆?br>
璁懼鍒墮犲晢寮鍙戠殑Ndis miniport driver鐩存帴璋冪敤NDIS搴撲腑鐨勬帴鍙e嚱鏁幫紝鍥犳涓嶉渶瑕佽冭檻閲嶅叆鐨勯棶棰橈紝灝辨槸涓涓姹傚皻鏈粨鏉熺殑鏃跺欙紝鏂扮殑璇鋒眰鍙堣繘鏉ヤ簡銆侼DIS搴撳璇鋒眰榪涜浜嗗簭鍒楀寲錛屼絾鏄繖縐嶅簭鍒楀寲涔熷Θ紕嶄簡澶氬鐞嗗櫒鐨勬墿灞曟с傛墍浠DIS5涓彁渚涗簡闈炲簭鍒楀寲鐨勬搷浣滈」銆備笅闈紝鎴戞潵浠嬬粛涓涓嬶紝Deserialized鍜孲erialized minport driver鐨勫尯鍒細
Deserialized NDIS miniport driver鑷繁搴忓垪鍖栧MinportXxx鍑芥暟鐨勬搷浣滐紝鎺掗槦鍜岀鐞嗗涓茍鍙戣姹傜殑浠誨姟閮界敱椹卞姩紼嬪簭鑷繁鏉ュ畬鎴愩傝孲erialized NDIS miniport driver浠ヤ笂鐨勫伐浣滈兘鏄緷璧栦簬NDIS搴撴潵瀹屾垚鐨勩備粠鎬ц兘瑙掑害鐪嬶紝Deserialized NDIS miniport driver鐨勬ц兘鏄疭erialized NDIS miniport driver鎬ц兘鐨?鍊嶅錛屾墍浠ュ埌NDIS6.0涔嬪悗鐨勬墍鏈塎iniport driver閮芥槸deserialize鐨勩?br>
浠ヤ笂鏄垜鍙傝僊SDN浠ュ強鑷繁鐨勪竴浜涚悊瑙g敾鍑烘潵鐨剋indows緗戠粶鏋舵瀯鍥撅紝涓嬮潰鎴戝氨浠庝笂鍒頒笅鏉ョ畝鍗曚粙緇嶄竴涓嬪叾涓殑鍚勪釜灞傘?/span>
1. 緗戠粶搴旂敤紼嬶紝Network applicantion錛岀敤鎴鋒佺殑搴旂敤紼嬪簭璋冪敤Windows鎿嶄綔緋葷粺鎻愪緵鐨勭綉緇淎PI錛岀綉緇淎PI鍖呮嫭錛?br>a) Windows濂楁帴瀛楋紙winsock錛?br>b) 榪滅▼榪囩▼璋冪敤RPC
c) Web璁塊棶API
d) 鍛藉悕綆¢亾鍜岄偖浠舵Ы
e) 鍏朵粬緗戠粶API
榪欎簺API鏃㈠彲浠ュ湪鐢ㄦ埛妯″紡涓嬪疄鐜幫紝涔熷彲浠ュ悓鏃跺湪鐢ㄦ埛妯″紡鍜屽唴鏍告ā寮忎笅瀹炵幇銆備粠鏈川涓婅榪欎簺API鏄笅灞傛彁渚涙帴鍙g殑鍙︿竴灞傚皝瑁呰屽凡銆?br>2. TDI Clients錛屼紶杈撻┍鍔ㄧ▼搴忔帴鍙e鎴鳳紝鏄唴鏍告ā寮忕殑璁懼椹卞姩紼嬪簭錛岀敤浜庡疄鐜扮綉緇淎PI鐨勫唴鏍擱儴鍒嗐傚皢緗戠粶API鐨勮姹傝漿鎹㈡垚IRP錛岄氳繃TDI鏍囧噯鏍煎紡鍖栧悗錛屽彂閫佺粰涓嬪眰鐨勫崗璁┍鍔紙涔熷氨鏄疶DI浼犺緭鍣級銆備粠sockets emulator鐨勬灦鏋勫浘鐪嬪埌錛孴DI Clients鐨勫疄鐜板彲浠ユ湁鐢ㄦ埛鎬佺殑閮ㄥ垎錛屼篃鏈夊唴鏍告佺殑閮ㄥ垎銆侫FD杈呭姪鍔熻兘椹卞姩紼嬪簭閫氳繃鍚戝崗璁┍鍔ㄧ▼搴忓彂閫乀DI IRP鏉ユ墽琛岀綉緇滃鎺ュ瓧鎿嶄綔錛屾瘮濡傚彂閫佸拰鎺ュ彈娑堟伅銆侫FD娌℃湁涓嶆槸紜畾浣跨敤鍝竴涓崗璁┍鍔紝鑰屾槸涓婂眰閫氱煡鍏惰浣跨敤鐨勫崗璁悕縐幫紝鐒跺悗AFD鍘繪墦寮鐩稿簲鍗忚鐨勮澶囧璞°?/span>
3. TDI Transport Providers銆乀DI浼犺緭鍣ㄣ丯DIS鍗忚椹卞姩紼嬪簭銆佸崗璁┍鍔ㄧ▼搴忥紝鎵鏈夎繖浜涘叾瀹炲氨鏄寚鐨勫悓涓涓笢瑗匡紝鎴戝湪鍚庨潰灝辯О鍏朵負鍗忚椹卞姩紼嬪簭銆傝繖涓儴鍒嗗氨鏄垜浠鏌愪釜鍗忚鐨勫叿浣撳疄鐜伴儴鍒嗐傚仛榪囩綉緇滃崗璁紑鍙戠殑鏈嬪弸涓瀹氱煡閬擄紝鍗忚鍏跺疄灝辨槸鍙屽彂鍗忓晢濂界殑涓濂楅氫俊鐨勮鍒欍備互IP鍗忚涓轟緥錛屽疄闄呬笂灝辨槸瀵圭綉緇滄暟鎹殑涓縐嶅鐞嗘柟寮忥紝鏍規嵁緗戠粶鏁版嵁鍖呯殑瑙f瀽緇撴瀯錛屽仛鍑虹浉搴旂殑澶勭悊銆俉indows鐨則cpip.sys灝卞疄鐜頒簡澶氫釜鍗忚錛宨p銆乼cp銆乽dp銆乤rp銆乮cmp銆乮gmp錛屽畠涓轟笂灞傜殑TDI Clients鎻愪緵浜?涓澶囧璞★紝鐢ㄤ簬璁塊棶浣跨敤榪欎簺鍗忚錛孴DI Clients鎵撳紑榪欎簺璁懼瀵硅薄錛屽悜鍏跺彂閫両RP璇鋒眰鏉ュ疄鐜拌嚜宸辯殑鎿嶄綔銆傞氳繃DDK鐨凞eviceTree鎴戜滑鍙互寰楀埌榪欎簺璁懼瀵硅薄
a) \Device\Rawip
b) \Device\Tcp
c) \Device\Udp
d) \Device\IPMULTICAST
e) \Device\Ip
鍗忚椹卞姩紼嬪簭澶勭悊鐨勬暟鎹槸閫氳繃NDIS搴撲腑鎻愪緵鐨勬帴鍙f潵鑾峰彇鐨勶紝涓嶉渶瑕佸彂閫両RP鏉ュ彇寰椼傚湪DDK XP涓彁渚涗簡涓涓崗璁┍鍔ㄧ▼搴忎簡婧愮▼搴廚disuio錛孌DK XP鍚庣殑鐗堟湰鎻愪緵鐨勬槸Ndisport銆傚湪DriverEntry涓垜浠彲浠ョ湅鍒幫紝椹卞姩紼嬪簭涓寮濮嬪氨娉ㄥ唽浜嗕竴涓狽DIS_PROTOCOL_CHARACTERISTICS錛岃繖涓粨鏋勪綋涓槸涓鍫哊disXxxx鍑芥暟銆侼DIS瑙勮寖鍦ㄨ繖閲屽氨寮濮嬪彂鎸ュ畠鐨勪綔鐢ㄤ簡銆?br>鍗忚椹卞姩紼嬪簭鐨勫彟涓涓綔鐢ㄥ氨鏄洃鍚綉緇滄暟鎹紝鑷繁寮鍙戜竴涓綉緇滃崗璁氳繃Ndis API鑾峰緱鎵鏈夌殑緗戠粶鏁版嵁錛屼絾鏄笉鑳藉鎷︽埅緗戠粶鏁版嵁錛屽洜涓哄叾浠栧崗璁┍鍔ㄤ篃鍙互閫氳繃Nids API鑾峰彇鏁版嵁銆備竴涓吀鍨嬬殑搴旂敤灝辨槸Winpcap浜嗭紝浣跨敤NPF.SYS鏉ユ崟鑾風綉緇滄暟鎹紝騫朵笖鍋氬ソ鍏呭垎緙撳啿澶勭悊錛岄槻姝㈠ぇ鏁版嵁閲忓埌鏉ユ椂鍑虹幇鏁版嵁鍖呬涪澶辯殑鎯呭喌銆傝鎯呮儏鑺倃inpcap鐨勫紑婧愪唬鐮併?br>鍏蜂綋鐨勫崗璁┍鍔ㄥ紑鍙戣繃紼嬶紝鎴戝氨涓嶇粏榪頒簡錛屽ぇ瀹跺彲浠ュ弬鐪婲disuio鍜孌DK doc錛屾垜鎺ㄨ崘boywhp鐨勪竴綃囨枃妗c奛DIS鍗忚椹卞姩寮鍙戙嬬粰澶у銆?br>4. NDIS錛孨etwork Driver Interface Specification錛岀綉緇滃崗璁帴鍙f爣鍑嗐備粠鍥句腑鎴戜滑鍙互鐪嬪埌鍖呰9鍦ㄥ叾涓殑涓や釜椹卞姩紼嬪簭錛屼竴涓槸NDIS intermediate driver錛孨DIS涓棿灞傞┍鍔ㄧ▼搴忥紝鍙︿竴涓槸NDIS minport driver錛屽皬绔彛椹卞姩紼嬪簭銆備笅闈㈢畝鍗曚粙緇嶄竴涓嬭繖涓や釜椹卞姩紼嬪簭錛?br>a) Ndis intermediate driver錛孨DIS涓棿灞傞┍鍔ㄧ▼搴忥紝瀵逛簬涓婂眰鐨刾rotocol driver瀹冨厖褰搈inport driver鐨勪綔鐢紝瀵逛簬涓嬪眰鐨刴inport driver瀹冨厖褰撲竴涓猵rotocol driver鐨勪綔鐢紝鎵浠ュ湪椹卞姩紼嬪簭DriverEntry涓氨娉ㄥ唽NDIS_PROTOCOL_CHARACTERISTICS鍜孨DIS_MINIPORT_CHARACTERISTICS錛屼嬌鐢╬rotocol characteristics涓璑DIS API浠巑iniport driver閭i噷鍙栧緱鏁版嵁鍖咃紝鍐嶇敤miniport characteristics鐨凬DIS API鍚戜笂灞傜殑protocol driver鍙戦佹暟鎹寘銆侼ids intermediate driver鏈澶х殑浼樺娍灝辨槸鎵鏈塵iniport driver鐨勬暟鎹寘閮借閫氳繃瀹冭繖閲屽掓墜緇檖rotocol driver錛屾墍浠ョ綉緇滈槻鐏灝辯湅涓婁簡榪欏潡椋庢按瀹濆湴銆傜幇鍦ㄥ緢澶氱綉緇滈槻鐏閮戒嬌鐢∟DIS intermediate driver鍋氭暟鎹寘鐨勮繃婊ゅ拰鎷︽埅宸ヤ綔錛岃繃婊ょ殑瑙勫垯璁劇疆鍒癕PSendPackets錛孭TReceive錛孭TReceiveRacket榪欎笁涓嚱鏁般傚叿浣撳紑鍙戣繃紼嬭澶у鍙傝僁DK鎻愪緵鐨凱assThru婧愪唬鐮侊紝www.ndis.com錛?nbsp;緗戜笂鏈夊緢澶氱浉鍏崇殑璧勬枡銆?br>NDIS 6.0涔嬪悗錛宖ilter driver灝卞彇浠d簡Ndis intermediate driver錛學DK涓彁渚涙簮鐮併?br>b) Ndis miniport driver涓鑸槸鐢辮澶囧巶鍟嗘彁渚涚殑錛屽湪DDK涓篃鎻愪緵浜唌iniport driver鐨勪竴涓緥瀛恊100bex錛屾敮鎸両ntel EtherExpressTM PRO/100+ Ethernet PCI adapter 鍜孖ntel EtherExpressTM PRO/100B PCI adapter涓ゆ緗戠粶閫傞厤鍣ㄣ?br>5. 鏈鍚庝粙緇嶄竴涓嬫葷嚎錛岃綆楁満鎬葷嚎鏈夊ソ鍑犵錛孶SB鎬葷嚎銆両SA鎬葷嚎銆丳CI鎬葷嚎銆佽櫄鎷熸葷嚎絳夛紝涓鑸兘鏄互PCI鎬葷嚎浣滀負鏍規葷嚎錛屽湪Windows緋葷粺涓叾浠栫殑鎬葷嚎鍙互鐞嗚В涓篜CI鎬葷嚎涓婄殑涓涓澶囥侾CI鎬葷嚎浣滀負鏍規葷嚎錛屽叾浼犺緭閫熷害杈冮珮錛屽彲浠ヨ揪鍒?33MB/S錛屾樉鍗″拰緗戝崱寰堝閮芥槸鐢≒CI鎻掓Ы銆?br>PCI-ISA妗ヨ澶囷紝涔熺О涓哄崡妗ワ紝瀹炵幇浜咺SA鎬葷嚎涓嶱CI鎬葷嚎鐨勬ˉ鎺ワ紝 鍗楁ˉ榪樺寘鎷粓绔両DE銆乁SB銆丏MA絳夋帶鍒跺櫒璁懼銆傚叾涓璘SB-HOST璁懼瀹炵幇浜哢SB鎬葷嚎鍜孭CI鎬葷嚎鐨勬ˉ鎺ャ侶OST/PCI妗ョО涓哄寳妗ワ紝鏄富澶勭悊鍣ㄤ腑蹇冨晩鍒板熀紜PCI灞閮ㄦ葷嚎銆傚崡妗ュ拰鍖楁ˉ緇勬垚浜嗕富鏉跨殑鑺墖緇勶紝閫氳繃鑺墖鐨勬墿灞曞疄鐜頒簡澶氱鎬葷嚎涓庡熀紜PCI灞閮ㄦ葷嚎鐨勬ˉ鎺ャ?br>鎬葷嚎椹卞姩紼嬪簭鍜孭NP綆$悊鍣ㄥ疄鐜頒簡鍗蟲彃鍗崇敤鐨勫姛鑳斤紝鐗╃悊璁懼瀵硅薄PDO灝辨槸鐢辨葷嚎椹卞姩紼嬪簭浜х敓鐨勩?/span>
1.2 澧炲姞鍔ㄤ綔
姝ゆ椂鎴戜滑灝嗗彧鐢ㄤ竴縐嶅姩浣滐細transitions錛屾垜浠湪涓嬮潰鐨勪唬鐮佷腑鎻掑叆浜嗛粦浣撶殑閮ㄥ垎銆?/span>
鐜板湪鎴戜滑鏈変簡鎵鏈夌殑鐘舵侊紝騫跺湪閫傚綋鐨勪綅緗鍔犱簡鎵鏈夌殑榪佺Щ鍔ㄤ綔錛屽悓鏃舵垜浠篃鍚慡topWatch鍙戦佷簡涓浜涗簨浠躲傝繖涓姸鎬佹満浼氬敖鑱屽敖璐g殑鎸夋垜浠殑甯屾湜榪涜鐘舵佽縼縐伙紝浣嗕緷鐒剁幇鍦ㄨ繕娌℃湁鍏跺畠鐨勫姩浣溿?/span>
1.3 State-local瀛樺偍
涓嬩竴姝ユ垜浠皢璁╄繖涓猄top watch鐪熸鐨勮褰曟椂闂翠簡銆傛牴鎹畇top watch鎵澶勪笉鍚岀殑鐘舵侊紝鎴戜滑闇瑕佷笉鍚岀殑鍙橀噺銆?/span>
l Stopped鐘舵侊細闇瑕佷竴涓繚瀛橀濆幓鏃墮棿鐨勫彉閲忋?/span>
l Running鐘舵侊細闇瑕佷竴涓繚瀛橀濆幓鏃墮棿鐨勫彉閲忥紝榪橀渶瑕佷竴涓繚瀛樹笂涓嬈″惎鍔ㄧ殑鏃墮棿鐐圭殑鍙橀噺銆?/span>
鏃犺鐘舵佹満鍦ㄤ粈涔堢姸鎬佷笅錛屾垜浠兘蹇呴』瑙傚療閫濆幓鏃墮棿榪欎釜鍙橀噺銆傛澶栵紝褰撴垜浠悜鐘舵佹満鍙戦丒vReSet浜嬩歡鏃訛紝榪欎釜鍙橀噺搴旇琚疆涓?銆傚叾瀹冪殑鍙橀噺鍙槸鐘舵佹満鍦≧unning鐘舵佹椂闇瑕併傛棤璁轟綍鏃舵垜浠繘鍏unning鐘舵佹椂錛屽畠搴旇琚疆涓虹郴緇熸椂閽熺殑褰撳墠鏃墮棿銆傚綋鎴戜滑閫鍑篟unning鐘舵佹椂錛屾垜浠粎浠呬粠緋葷粺鏃墮挓鐨勫綋鍓嶆椂闂村噺鍘誨紑濮嬫椂闂達紙榪涘叆鏃惰褰曠殑鏃墮棿錛夛紝灝嗙粨鏋滃姞鍒伴濆幓鏃墮棿閲屽氨鍙互浜嗐?/span>
榪欎釜鐘舵佹満鐜板湪鍙互嫻嬮噺鏃墮棿浜嗭紝浣嗘槸鎴戜滑榪樹笉鑳界湅鍒扮粨鏋溿?/span>
鍦ㄨ繖閲岋紝State-local storage鐨勪紭鍔胯繕娌℃湁瀹屾垚鏄劇幇鍑烘潵銆傚湪FAQ欏圭洰“State-local storage閰峰湪鍝噷錛?#8221;涓紝浼氶氳繃涓庝竴涓病鏈夌敤State-local storage鐨凷top Watch鐨勬瘮杈冩潵璇存槑銆?/span>
1.4 鍦ㄧ姸鎬佹満澶栧緱鍒扮姸鎬佷俊鎭?/span>
涓轟簡鍙栧緱嫻嬮噺鐨勬椂闂達紝鎴戜滑闇瑕佷竴涓粠鐘舵佹満澶栧緱鍒扮姸鎬佷俊鎭殑鏈哄埗銆傛寜鎴戜滑鐜板湪鐨勭姸鎬佹満璁捐錛屽彲浠ユ湁涓ょ鏂規硶銆備負綆鍗曡搗瑙侊紝鎴戜滑鍦ㄨ繖閲岀敤涓涓綆鏁堢殑鏂瑰紡錛歴tate_cast<>()(鍦⊿topWatch2.cpp涓垜浠細鐢ㄤ竴涓◢澶嶆潅涓鐐圭殑鏇夸唬鏂規硶)錛?span style="COLOR: #000080">璇戣呮敞錛氬湪StopWatch2.cpp涓槸鍚戠姸鎬佹満鍙戦佷竴涓彇寰楅濆幓鏃墮棿鐨勪簨浠訛紝浠庝簨浠舵垚鍛橀噺涓皢閫濆幓鏃墮棿甯﹀洖鏉?/span> 錛夛紝浠庡瓧闈㈡剰鎬濆氨鍙互鐪嬪嚭錛屽畠鍦ㄨ涔変笂涓巇ynamic_cast鏈夌偣鐩鎬技銆備緥濡傦紝褰撴垜浠皟鐢╩yWatch.state_cast<const Stpped&>()鏃訛紝褰撶姸鎬佹満鍦⊿topped鐘舵佹椂錛屾垜浠細寰楀埌涓涓猄topped鐘舵佺被鐨勫紩鐢ㄣ傚惁鍒欙紝浼氭姏鍑簊td::bad_cast寮傚父銆傛垜浠彲浠ュ埄鐢ㄨ繖涓姛鑳芥潵瀹炵幇涓涓猄topWatch鐨勬垚鍛樺嚱鏁幫紝璁╁畠鐨勭粨鏋滆繑鍥為濆幓鐨勬椂闂淬傜劧鑰岋紝鎴戜滑涓嶆槸鍏堥棶涓涓嬬姸鎬佹満鍦ㄤ粈涔堢姸鎬侊紝鐒跺悗鍐嶅幓鐢ㄤ笉鍚岀殑鏂規硶璁$畻閫濆幓鏃墮棿錛岃屾槸灝嗚綆楁斁鍒癝topped鍜孯unning鐘舵佷腑錛岀敤涓涓帴鍙f潵鑾峰緱閫濆幓閫濆幓鏃墮棿銆?/span>
涓轟簡紜疄鐪嬪埌琚祴閲忕殑鏃墮棿錛屼綘搴旇鎯沖姙娉曞湪main()涓崟姝ユ墽琛屻係topWatch渚嬪瓙灝嗚繖涓▼搴忔墿灞曚負涓涓氦浜掑紡鐨勭粓绔▼搴忎簡銆?/span>
榪欎釜浠g爜宸茬粡鍙互緙栬瘧浜嗭紝浣嗕笉浼氬彂鐢熶換浣曞彲瀵熻鐨勪簨浠躲?br>
鑷劧鐣岀殑棰滆壊鍗冨彉涓囧寲錛屼負浜嗙粰棰滆壊涓涓噺鍖栫殑琛¢噺鏍囧噯錛屽氨闇瑕佸緩绔嬭壊褰╃┖闂存ā鍨嬫潵鎻忚堪鍚勭鍚勬牱鐨勯鑹詫紝鐢變簬浜哄鑹插僵鐨勬劅鐭ユ槸涓涓鏉傜殑鐢熺悊鍜屽績鐞嗚仈鍚堜綔鐢?鐨勮繃紼嬶紝鎵浠ュ湪涓嶅悓鐨勫簲鐢ㄩ鍩熶腑涓轟簡鏇村ソ鏇村噯紜殑婊¤凍鍚勮嚜鐨勯渶姹傦紝灝卞嚭鐜頒簡鍚勭鍚勬牱鐨勮壊褰╃┖闂存ā鍨嬫潵閲忓寲鐨勬弿榪伴鑹層傛垜浠瘮杈冨父鎺ヨЕ鍒扮殑灝卞寘鎷?RGB / CMYK / YIQ / YUV / HSI絳夌瓑銆?/p>
瀵逛簬鏁板瓧鐢靛瓙澶氬獟浣撻鍩熸潵璇達紝鎴戜滑緇忓父鎺ヨЕ鍒扮殑鑹插僵絀洪棿鐨勬蹇碉紝涓昏鏄疪GB , YUV榪欎袱縐嶏紙瀹為檯涓婏紝榪欎袱縐嶄綋緋誨寘鍚簡璁稿縐嶅叿浣撶殑棰滆壊琛ㄨ揪鏂瑰紡鍜屾ā鍨嬶紝濡俿RGB, Adobe RGB, YUV422, YUV420 …錛? RGB鏄寜涓夊熀鑹插姞鍏夌郴緇熺殑鍘熺悊鏉ユ弿榪伴鑹詫紝鑰孻UV鍒欐槸鎸夌収 浜害錛岃壊宸殑鍘熺悊鏉ユ弿榪伴鑹層?/p>
鍗充嬌鍙槸RGB YUV榪欎袱澶х被鑹插僵絀洪棿錛屾墍娑夊強鍒扮殑鐭ヨ瘑涔熸槸鍗佸垎涓板瘜澶嶆潅鐨勶紝鑷煡涓嶅叿澶囪凍澶熺殑鐩稿叧涓撲笟鐭ヨ瘑錛屾墍浠ユ湰鏂囦富瑕侀拡瀵瑰伐紼嬮鍩熺殑搴旂敤鍙婄畻娉曡繘琛岃璁恒?/p>
2 YUV鐩稿叧鑹插僵絀洪棿妯″瀷
2.1 YUV 涓?YIQ YcrCb
瀵逛簬YUV妯″瀷錛屽疄闄呬笂寰堝鏃跺欙紝鎴戜滑鏄妸瀹冨拰YIQ / YCrCb妯″瀷娣蜂負涓璋堢殑銆?/p>
瀹為檯涓?YUV妯″瀷鐢ㄤ簬PAL鍒跺紡鐨勭數瑙嗙郴緇燂紝Y琛ㄧず浜害錛孶V騫墮潪浠諱綍鍗曡瘝鐨勭緝鍐欍?/p>
YIQ妯″瀷涓嶻UV妯″瀷綾諱技錛岀敤浜嶯TSC鍒跺紡鐨勭數瑙嗙郴緇熴俌IQ棰滆壊絀洪棿涓殑I鍜孮鍒嗛噺鐩稿綋浜庡皢YUV絀洪棿涓殑UV鍒嗛噺鍋氫簡涓涓?3搴︾殑鏃嬭漿銆?/p>
YCbCr棰滆壊絀洪棿鏄敱YUV棰滆壊絀洪棿媧劇敓鐨勪竴縐嶉鑹茬┖闂達紝涓昏鐢ㄤ簬鏁板瓧鐢佃緋葷粺涓備粠RGB鍒癥CbCr鐨勮漿鎹腑錛岃緭鍏ャ佽緭鍑洪兘鏄?浣嶄簩榪涘埗鏍煎紡銆?/p>
涓夎呬笌RGB鐨勮漿鎹㈡柟紼嬪涓嬶細
RGB -> YUV錛?/p>
瀹為檯涓婁篃灝辨槸錛?/p>
Y=0.30R+0.59G+0.11B 錛?U=0.493(B錛峐) 錛?V=0.877(R錛峐)
RGB -> YIQ錛?/p>
RGB -> YCrCb錛?/p>
浠庡叕寮忎腑錛屾垜浠叧閿鐞嗚В鐨勪竴鐐規槸錛孶V / CbCr淇″彿瀹為檯涓婂氨鏄摑鑹插樊淇″彿鍜岀孩鑹插樊淇″彿錛岃繘鑰岃█涔嬶紝瀹為檯涓婁竴瀹氱▼搴︿笂闂存帴鐨勪唬琛ㄤ簡钃濊壊鍜岀孩鑹茬殑寮哄害錛岀悊瑙h繖涓鐐瑰浜庢垜浠悊瑙e悇縐嶉鑹插彉鎹㈠鐞嗙殑榪囩▼浼氭湁寰堝ぇ鐨勫府鍔┿?/p>
鎴戜滑鍦ㄦ暟瀛楃數瀛愬濯掍綋棰嗗煙鎵璋堝埌鐨刌UV鏍煎紡錛屽疄闄呬笂鍑嗙‘鐨勮錛屾槸浠crCb鑹插僵絀洪棿妯″瀷涓哄熀紜鐨勫叿鏈夊縐嶅瓨鍌ㄦ牸寮忕殑涓綾婚鑹叉ā鍨嬬殑瀹舵棌錛堝寘鎷?YUV444 / YUV422 / YUV420 / YUV420P絳夌瓑錛夈傚茍涓嶆槸浼犵粺鎰忎箟涓婄敤浜嶱AL鍒舵ā鎷熺數瑙嗙殑YUV妯″瀷銆傝繖浜沋UV妯″瀷鐨勫尯鍒富瑕佸湪浜嶶V鏁版嵁鐨勯噰鏍鋒柟寮忓拰瀛樺偍鏂瑰紡錛岃繖閲屽氨涓嶈榪般?/p>
鑰屽湪Camera Sensor涓紝鏈甯哥敤鐨刌UV妯″瀷鏄?YUV422鏍煎紡錛屽洜涓哄畠閲囩敤4涓瓧鑺傛弿榪頒袱涓儚绱狅紝鑳藉拰RGB565妯″瀷姣旇緝濂界殑鍏煎銆傛湁鍒╀簬Camera Sensor鍜孋amera controller鐨勮蔣紜歡鎺ュ彛璁捐銆?/p>
3 YUV2RGB蹇熺畻娉曞垎鏋?/p>
榪欓噷鎸囩殑YUV瀹為檯鏄痀crCb浜?8 ) YUV2RGB鐨勮漿鎹㈠叕寮忔湰韜槸寰堢畝鍗曠殑錛屼絾鏄壍娑夊埌嫻偣榪愮畻錛屾墍浠ワ紝濡傛灉瑕佸疄鐜板揩閫熺畻娉曪紝綆楁硶緇撴瀯鏈韓娌′粈涔堝ソ鐮旂┒鐨勪簡錛屼富瑕佹槸閲囩敤鏁村瀷榪愮畻鎴栬呮煡琛ㄦ潵鍔犲揩璁$畻閫熷害銆?br>棣栧厛鍙互鎺ㄥ寰楀埌杞崲鍏紡涓猴細
R = Y + 1.4075 *錛圴-128錛?br> G = Y – 0.3455 *錛圲 –128錛?– 0.7169 *錛圴 –128錛?br> B = Y + 1.779 *錛圲 – 128錛?/p>
3.1 鏁村瀷綆楁硶
瑕佺敤鏁村瀷榪愮畻浠f浛嫻偣榪愮畻錛屽綋鐒舵槸瑕佺敤縐諱綅鐨勫姙娉曚簡錛屾垜浠彲浠ュ緢瀹規槗寰楀埌涓嬪垪綆楁硶錛?/p>
u = YUVdata[UPOS] - 128;
v = YUVdata[VPOS] - 128;
rdif = v + ((v * 103) >> 8);
invgdif = ((u * 88) >> 8) +((v * 183) >> 8);
bdif = u +( (u*198) >> 8);
r = YUVdata[YPOS] + rdif;
g = YUVdata[YPOS] - invgdif;
b = YUVdata[YPOS] + bdif;
涓轟簡闃叉鍑虹幇婧㈠嚭錛岃繕闇瑕佸垽閿欒綆楃殑緇撴灉鏄惁鍦?-255鑼冨洿鍐咃紝鍋氱被浼間笅闈㈢殑鍒ゆ柇銆?/p>
if (r>255)
r=255;
if (r<0)
r=0;
瑕佷粠RGB24杞崲鎴怰GB565鏁版嵁榪樿鍋氱Щ浣嶅拰鎴栬繍綆楋細
RGBdata[1] =( (r & 0xF8) | ( g >> 5) );
RGBdata[0] =( ((g & 0x1C) << 3) | ( b >> 3) );
3.2 閮ㄥ垎鏌ヨ〃娉?/p>
鏌ヨ〃娉曢鍏堝彲浠ユ兂鍒扮殑灝辨槸鐢ㄦ煡琛ㄦ浛浠d笂榪版暣鍨嬬畻娉曚腑鐨勪箻娉曡繍綆椼?/p>
rdif = fac_1_4075[u];
invgdif = fac_m_0_3455[u] + fac_m_0_7169[v];
bdif = fac_1_779[u];
榪欓噷涓鍏遍渶瑕?涓?緇存暟緇勶紝涓嬫爣浠?寮濮嬪埌255錛岃〃鏍煎叡鍗犵敤綰?K鐨勫唴瀛樼┖闂淬倁v鍙互涓嶉渶瑕佸仛鍑?28鐨勬搷浣滀簡銆傚湪浜嬪厛璁$畻瀵瑰簲鐨勬暟緇勫厓绱犵殑鍊肩殑鏃跺欒綆楀湪鍐呭氨濂戒簡銆?/p>
瀵逛簬姣忎釜鍍忕礌錛岄儴鍒嗘煡琛ㄦ硶鐢ㄦ煡琛ㄦ浛浠d簡2嬈″噺娉曡繍綆楀拰4嬈′箻娉曡繍綆楋紝4嬈$Щ浣嶈繍綆椼備絾鏄紝渚濈劧闇瑕佸嬈″姞娉曡繍綆楀拰6嬈℃瘮杈冭繍綆楀拰鍙兘瀛樺湪鐨勮祴鍊兼搷浣滐紝鐩稿絎竴縐嶆柟娉曡繍綆楅熷害鎻愰珮騫朵笉鏄庢樉銆?/p>
3.3 瀹屽叏鏌ヨ〃娉?/p>
閭d箞鏄惁鍙互鐢盰UV鐩存帴鏌ヨ〃寰楀埌瀵瑰簲鐨凴GB鍊煎憿錛熶箥涓鐪嬩技涔庝笉澶彲鑳斤紝浠ユ渶澶嶆潅鐨凣鐨勮繍綆椾負渚嬶紝鍥犱負G涓嶻UV涓夎呴兘鐩稿叧錛屾墍浠ョ被浼?G=YUV2G[Y][U][V]榪欐牱鐨勭畻娉曪紝涓涓笁緇翠笅鏍囧昂瀵擱兘涓?56鐨勬暟緇勫氨闇瑕佸崰鐢?鐨?4嬈℃柟綰?6鍏嗙┖闂達紝緇濆鏄病娉曟帴鍙楃殑銆傛墍浠ョ洰鍓嶅鏁伴兘 鏄噰鐢ㄩ儴鍒嗘煡琛ㄦ硶銆?/p>
浣嗘槸錛屽鏋滄垜浠粩緇嗗垎鏋愬氨鍙互鍙戠幇錛屽浜嶨鎴戜滑瀹為檯涓婂畬鍏ㄦ病鏈夊繀瑕侀噰鐢ㄤ笁緇存暟緇勶紝鍥犱負Y鍙笌UV榪愮畻鐨勭粨鏋滅浉鍏籌紝涓嶶V鐨勪釜浣撴棤鍏籌紝鎵浠ユ垜浠彲浠ラ噰鐢ㄤ簩嬈℃煡琛ㄧ殑鏂規硶灝咷鐨勮繍綆楃畝鍖栦負瀵逛袱涓簩緇存暟緇勭殑鏌ヨ〃鎿嶄綔錛屽涓嬶細
G = yig2g_table[ y ][ uv2ig_table[ u ][ v ] ]錛?/p>
鑰孯B鏈韓灝卞彧鍜孻U鎴朰V鐩稿叧錛屾墍浠ヨ繖鏍鋒垜浠竴鍏遍渶瑕?涓?*8鐨勪簩緇磋〃鏍鹼紝闇瑕佸崰鐢?涔?鐨?6嬈℃柟鍏?56K鍐呭瓨銆傚熀鏈彲浠ユ帴鍙椼備絾鏄浜庢墜鏈鴻繖鏍風殑宓屽叆寮忚繍鐢ㄦ潵璇達紝榪樻槸鐣ユ湁浜涘ぇ浜嗐?/p>
榪涗竴姝ュ垎鏋愶紝鎴戜滑鍙互鐪嬪埌錛屽洜涓哄湪鎵嬫満絳夊祵鍏ュ紡榪愮敤涓婃垜浠渶緇堟槸瑕佹妸鏁版嵁杞崲鎴怰GB565鏍煎紡閫佸埌LCD灞忎笂鏄劇ず鐨勶紝鎵浠ワ紝瀵逛簬RGB涓夊垎閲忔潵璇達紝鎴戜滑 鏍規湰涓嶉渶瑕?bit榪欎箞楂樼殑綺懼害錛屼負浜嗙畝鍗曞拰榪愮畻鐨勭粺涓璧瘋錛屽姣忎釜鍒嗛噺鎴戜滑鍏跺疄鍙渶瑕侀珮6bit鐨勬暟鎹氨瓚沖浜嗭紝鎵浠ユ垜浠彲浠ヨ繘涓姝ユ妸琛ㄦ牸鏀逛負4涓?6*6鐨勪簩緇磋〃鏍鹼紝榪欐牱涓鍏卞彧闇瑕佸崰鐢?6K鍐呭瓨錛佸湪璁$畻琛ㄦ牸鍏冪礌鍊肩殑鏃跺欒繕鍙互鎶婃渶緇堢殑婧㈠嚭鍒ゆ柇涔熶簨鍏堝仛瀹屻傛渶鍚庣殑綆楁硶濡備笅錛?/p>
y = (YUVdata[Y1POS] >> 2);
u = (YUVdata[UPOS] >> 2);
v = (YUVdata[VPOS] >> 2);
r = yv2r_table[ y ][ v ];
g = yig2g_table[ y ][ uv2ig_table[ u ][ v ] ];
b = yu2b_table[ y ][ u ];
RGBdata[1] =( (r & 0xF8) | ( g >> 5) );
RGBdata[0] =( ((g & 0x1C) << 3) | ( b >> 3) );
榪欐牱鐩稿閮ㄥ垎鏌ヨ〃娉曪紝鎴戜滑澧炲姞浜?嬈$Щ浣嶈繍綆楋紝鑰岃繘涓姝ュ噺灝戜簡4嬈″姞娉曡繍綆楀拰6嬈℃瘮杈冭祴鍊兼搷浣溿?/p>
鍦ㄨ綆楄〃鏍煎厓绱犳暟鍊肩殑鏃跺欙紝瑕佽冭檻鑸嶅叆鍜屽亸縐葷瓑鍥犳暟浣垮緱璁$畻鐨勪腑闂寸粨鏋滄弧瓚蟲暟緇勪笅鏍囬潪璐熺殑瑕佹眰錛岄渶瑕佷竴瀹氱殑鎶宸с?/p>
閲囩敤瀹屽叏鏌ヨ〃娉曪紝鐩稿浜庣涓縐嶇畻娉曪紝鏈緇堣繍綆楅熷害鍙互鏈夋瘮杈冩槑鏄劇殑鎻愰珮錛屽叿浣撴ц兘鑳芥彁楂樺灝戯紝瑕佺湅鎵鍦ㄥ鉤鍙扮殑CPU榪愮畻閫熷害鍜屽唴瀛樺瓨鍙栭熷害鐨勭浉瀵規瘮渚嬨傚唴 瀛樺瓨鍙栭熷害瓚婂揩錛岀敤鏌ヨ〃娉曞甫鏉ョ殑鎬ц兘鏀瑰杽瓚婃槑鏄俱傚湪鎴戠殑PC涓婃祴璇曠殑緇撴灉鎬ц兘澶х害鑳芥彁楂?5%銆傝屽湪鏌怉RM騫沖彴涓婃祴璇曞彧鎻愰珮浜嗙害15%銆?/p>
3.4 榪涗竴姝ョ殑鎬濊?/p>
瀹為檯涓婏紝涓婅堪綆楁硶錛?/p>
RGBdata[1] =( (r & 0xF8) | ( g >> 5) );
RGBdata[0] =( ((g & 0x1C) << 3) | ( b >> 3) );
涓殑 (r & 0xF8) 鍜?( b >> 3) 絳夎繍綆椾篃瀹屽叏鍙互鍦ㄨ〃鏍間腑浜嬪厛璁$畻鍑烘潵銆傚彟澶栵紝YU / YV鐨勫彇鍊煎疄闄呬笂涓嶅彲鑳借鐩栨弧6*6鐨勮寖鍥達紝涓棿鏈変簺鐐規槸姘歌繙鍙栦笉鍒扮殑鏃犺緭鍏ワ紝RB鐨勮繍綆椾篃鍙互鑰冭檻鐢?*5鐨勮〃鏍箋傝繖浜涢兘鍙兘榪涗竴姝ユ彁楂樿繍綆楃殑閫熷害錛屽噺 灝忚〃鏍肩殑灝哄銆?/p>
鍙﹀錛屽湪宓屽叆寮忚繍鐢ㄤ腑錛屽鏋滃彲鑳藉敖閲忓皢琛ㄦ牸鏀懼湪楂橀熷唴瀛樺SRAM涓簲璇ユ瘮鏀懼湪SDRAM涓洿鍔犺兘鍙戞尌鏌ヨ〃娉曠殑浼樺娍銆?/p>
4 RGB2YUV ?
鐩墠瑙夊緱榪欎釜鏄病娉曞皢3緇磋〃鏍肩殑鏌ヨ〃榪愮畻鍖栫畝涓?緇磋〃鏍肩殑鏌ヨ〃榪愮畻浜嗐傚彧鑳界敤閮ㄥ垎鏌ヨ〃娉曟浛浠e叾涓殑涔樻硶榪愮畻銆?/p>
鍙﹀錛屽鏁版儏鍐典笅錛屾垜浠渶瑕佺殑榪樻槸YUV2RGB鐨勮漿鎹紝鍥犱負浠嶴ensor寰楀埌鐨勬暟鎹氬父鎴戜滑浼氱敤YUV鏁版嵁錛屾澶朖PG鍜孧PEG瀹為檯涓婁篃鏄熀浜嶻UV鏍煎紡緙栫爜鐨勶紝鎵浠ヨ鏄劇ず瑙g爜鍚庣殑鏁版嵁闇瑕佺殑涔熸槸YUV2RGB鐨勮繍綆?8 錛夎繍姘旇繍姘斻?/p>
鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛?a >http://blog.csdn.net/ALENTAM/archive/2008/03/13/2178020.aspx