版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
象、IO完成端口、可等待定時器、互斥、事件、信號量等,這些都是‘可等待’對象,可用于WaitForSingleObject等函數(shù)。StructKSEMAPHORE{DISPATCHER_HEADERHeader;//公共頭LONGLimit;//最大信號量個數(shù)}Struct{…LONGSignalState;//信號狀態(tài)量(>0表示有信號,<=0表示無信號)LIST_ENTRYWaitListHead;//等待塊隊列…}INBOOLEertable,//表示本次等待操作是否可被吵醒(即被強制喚醒)INPLARGE_INTEGERTimeOutOPTIONAL)//超時{PVOIDObject,KPROCESSOR_MODEPreviousMode=ExGetPreviousMode();LARGE_INTEGERSafeTimeOut;NTSTATUSif((TimeOut)&&(PreviousMode!={{SafeTimeOut=ProbeForReadLargeInteger(TimeOut);TimeOut=&SafeTimeOut;}{_SEH2_YIELD(return}}Status=if{WaitableObject=OBJECT_TO_OBJECT_HEADER(Object)->Type->DefaultObject;if(IsPointerOffset(WaitableObject))//ifDefaultObject是個偏移,不是指針{WaitableObject=(PVOID)((ULONG_PTR)Object+}{=}{Status=}}return}#defineIsPointerOffset(Ptr)((LONG)(Ptr)>=如果是個偏移值,那么DefaultObject值的最為0,否則為1。象記錄在其對象類型的DefaultObject字段中。較大,函數(shù)也較長。重要的是對喚醒原因的理解。(把WaitStatus理解為喚醒原因就好了)NTSTATUS//返回值表示本次睡眠的喚醒原//注意下面的函數(shù)只能在DISPATCH_LEVEL以下調(diào)用,否則藍屏。(除非Timeout!=NULL&&*Timeout==0)KeWaitForSingleObject(INPVOIDObject,//要等待的‘可直接等待對象’INKWAIT_REASONWaitReason,//線程上次被切出原INKPROCESSOR_MODEWaitMode,//表示這是來自用戶模式/內(nèi)核模式的等待請求INBOOLEertable,//表示本次等待操作是否可以被強制喚醒INPLARGE_INTEGERTimeoutOPTIONAL)//超時{PKTHREADThread=PKMUTANTCurrentObject(PKMUTANT)Object;//其實意思是(DISPATCHER_HEADER*)ObjectPKWAIT_BLOCKWaitBlock=&Thread->WaitBlock[0];PKWAIT_BLOCKTimerBlock&Thread->WaitBlock[TIMER_WAIT_BLOCK];PKTIMERTimer=&Thread->Timer;//復(fù)用這個超時定時器NTSTATUSWaitStatus;//其實表示‘上次喚醒原因’BOOLEANSwappable;//內(nèi)核棧是否可換到外存LARGE_INTEGERDueTimeNewDueTimeInterruptTime;PLARGE_INTEGEROriginalDueTime=Timeout;ULONGHand=if(!Thread->WaitNext)gotoWaitStart;Thread->WaitNextFALSE;//復(fù){=//fir是AP_EVLKiwpontxIntrlPfrq是AP_EECPCif((Thread->ApcState.KernelApcPending)&&!(Thread->SpecialApcDisable)&&(Thread->WaitIrql==PASSIVE_LEVEL)){}1、所等待的對象有信號了2、被強制喚醒{if(CurrentObject->Header.Type==MutantObject){if((CurrentObject->Header.SignalState>0)||(Thread==CurrentObject->OwnerThread)){if(CurrentObject->Header.SignalState!={KiSatisfyMutantWait(CurrentObjectThread);WaitStatus=Thread->WaitStatus;//喚醒原因gotoDontWait;//退出函數(shù)}Else異常}}//普通的等待對象只要DISPATCHER_HEADER頭部中的SignalState0就表示有信號了elseif(CurrentObject->Header.SignalState>0){WaitStatus=STATUS_WAIT_0;//喚醒原因為‘真喚醒’gotoDontWait;退出函}WaitStatusKiCheckAlertability(Thread,AlertableWaitMode);ifWaitStatusSTATUS_WAIT_0)//if強制喚醒了,就break({InterruptTime.QuadPart=if((ULONGLONG)InterruptTime.QuadPart>=Timer-{WaitStatusSTATUS_TIMEOUT;//喚醒原因為‘超時’gotoDontWait;//退出函數(shù)}Timer->Header.Inserted=}if(Thread->Queue)KiActivateWaiterQueue(Thread->Queue);Thread->State=Waiting;//將線程標記為等待狀態(tài)(即睡眠狀態(tài))if(Timeout)
=,1、臨時喚醒。指被其他線程發(fā)來的內(nèi)核APC臨時喚醒,要求執(zhí)行緊急APC任務(wù)強if(WaitStatusSTATUS_KERNEL_APC)//if喚醒原因不是臨時喚醒,就退出函數(shù)了returnWaitStatus;(Timeout=}Thread->WaitIrqlKeRaiseIrqlToSynchLevel();}returnWaitStatus;}typedefstruct_KWAIT_BLOCK{struct_KTHREAD*Thread;//所屬線程struct_KWAIT_BLOCK*NextWaitBlock;//下一個等待塊(用來掛入線程的等待塊鏈表)USHORTWaitKey;//本等待塊是所屬線程的第幾個等待對象UCHARWaitType;//WaitAll/WaitAnyvolatileUCHARBlockState;}KWAIT_BLOCK,*PKWAIT_BLOCK,#defineThread->WaitBlockListWaitBlock;//等待塊鏈表WaitBlock->WaitKey=0;//即等待塊的索引WaitBlock->Object=Object;//要等待的目標對象Thread->WaitStatus=0;//復(fù)位喚醒原因if {}{}
KxSetTimerForThreadWait(Timer,*Timeout,&Hand);//設(shè)置好定時器對象DueTime.QuadPart=Timer->DueTime.QuadPart;TimerBlock->NextWaitBlock=WaitBlock;//單循環(huán)鏈表Timer->Header.WaitListHead.Flink=&TimerBlock->WaitListEntry;Timer->Header.WaitListHead.Blink=&TimerBlock-WaitBlock->NextWaitBlockWaitBlock;單循環(huán)鏈Thread->AlertableAlertable;//線程睡眠模式,是否可被提醒(即強制喚醒)Thread->WaitMode=WaitMode;//來自用戶還是內(nèi)核模式的等待請求Thread->WaitReasonWaitReason;上次線程切換原因Thread->WaitListEntry.Flink=NULL;SwappableKiCheckThreadStackSwap(Thread,WaitMode);//檢測本線程的內(nèi)核棧是否可以換到外存Thread->WaitTime=KeTickCount.Lort;//記錄上次切出時間的函數(shù)KiCheckThreadStackSwap用來檢測本線程的內(nèi)核棧是否可以置換到外存BOOLEANKiCheckThreadStackSwap(INPKTHREADThread,INKPROCESSOR_MODE{if((WaitMode==UserMode)&&(Thread->EnableStackSwap)(Thread->Priority>=(LOW_REALTIME_PRIORITY+{}{
returnreturn}}KiCheckAlertability(INPKTHREADINBOOLEertable,//本次睡眠操作是否支持強制喚醒{{{Thread->Alerted[WaitMode]=FALSE;//復(fù)位}elseif((WaitMode!=KernelMode)&&{Thread->ApcState.UserApcPending=}elseif(Thread->Alerted[KernelMode]){Thread->Alerted[KernelMode]=}}elseif((WaitModeKernelMode&&(Thread-{;//}return}不支持強制喚醒,也會被其他線程發(fā)來的用戶APC給強制搞醒。#defineKiAddThreadToWaitList(Thread,Swappable){if(Swappable)//為什么要滿足這個條件,我也搞不清InsertTailList(&KeGetCurrentPrcb()->WaitListHead,&Thread->WaitListEntry);}VOIDINKPRIORITYIncrement)//喚醒線程后的優(yōu)先級增量(以便盡快得到調(diào)度運行{PLIST_ENTRYWaitEntry,WaitList;PKWAIT_BLOCKWaitBlock;PKTHREADWaitThread;PKMUTANTFirstObject=ObjectPointer;NTSTATUSWaitStatus;WaitList=&FirstObject->Header.WaitListHead;WaitEntry=WaitList->Flink;while((FirstObject->Header.SignalState>0)&&(WaitEntry!={WaitBlock=CONTAINING_RECORD(WaitEntry,KWAIT_BLOCK,WaitListEntry);WaitThread=WaitBlock->Thread;WaitStatusSTATUS_KERNEL_APC;//模擬給那個等待者線程發(fā)送內(nèi)核apc而臨時喚醒它if(WaitBlock->WaitType==WaitAny)//WaitAnt類型的話,肯定滿足分配了{WaitStatus=(NTSTATUS)WaitBlock->WaitKey;//喚醒原因改為‘真喚醒’,此處即索引}KiUnwaitThread(WaitThread,WaitStatus,Increment);//關(guān)鍵函數(shù)WaitEntry=WaitList->Flink;//下一個線程}}擬給它發(fā)送內(nèi)核apc方式(其實沒發(fā)送),臨時喚醒它,進入下輪循環(huán),繼續(xù)測試它所等待的其他對象,#defineKiSatisfyObjectWait(Object,{if(Object)->Header.TypeMutantObject)互斥對象要特殊處{if((Object)->Header.SignalState==0)//if擁有計數(shù)==0{(Object)->OwnerThread=Thread->KernelApcDisable=Thread->KernelApcDisable-(Object)->ApcDisable;(({(Object)->AbandonedFALSE;//復(fù)=}}}elseif(((Object)->Header.Type&TIMER_OR_EVENT_TYPE)==EventSynchronizationObject)(Object)->Header.SignalState=0;elseif((Object)->Header.Type==}多只是要提醒一下,不管是什么同步對象,其的SignalState表示信號狀態(tài)量計數(shù),當(dāng)該值<=0時表示01兩種情況的‘特殊信號量’。VOIDKiUnwaitThread(INPKTHREADThread,//目INLONG_PTRWaitStatus,//喚醒原{,Thread->AdjustIncrementSCHAR)Increment;//上次優(yōu)先級調(diào)整增量Thread->AdjustReason=AdjustUnwait;//調(diào)整原因}每當(dāng)一個apc的時候,將調(diào)用下面的函數(shù)NTSTATUS{if(Thread!={if(ApcMode==KernelMode)//若要給其他線程一個內(nèi)核{Thread->ApcState.KernelApcPending=TRUE;if(Thread->State==Running){RequestInterrupt=}elseif((Thread->State==Waiting)&&(Thread->WaitIrql==PASSIVE_LEVEL)!(Thread->SpecialApcDisable)&&(!(Apc->NormalRoutine)||{Status=,,}}elseif((Thread->State==Waiting)&&(Thread->WaitMode==UserMode)&&((Thread->Alertable)||(Thread->ApcState.UserApcPending))){Thread->ApcState.UserApcPending=TRUE;Status=STATUS_USER_APC;}}VOIDKiUnlinkThread(INPKTHREADThread,INNTSTATUS{PKTIMERTimer;Thread->WaitStatus|=WaitStatus;WaitBlock=Thread-{WaitBlock=WaitBlock->NextWaitBlock;}while(WaitBlock!=Thread-if(Thread->WaitListEntry.Flink)RemoveEntryList(&Thread-Timer=&Thread-if(Timer->Header.Inserted)KxRemoveTreeTimer(Timer);if(Thread->Queue)Thread->Queue->CurrentCount++;}LONGKiSwapThread(INPKTHREADCurrentThread,INPKPRCB{BOOLEANApcState=KIRQLWaitIrql;//上次切出時的irqlLONG_PTRWaitStatus;//上次喚醒原因PKTHREADNextThread;NextThreadPrcb->NextThread;//當(dāng)前的搶占者線程if(NextThread){}{
Prcb->NextThread=Prcb->CurrentThread=NextThread;NextThread->State=Running;NextThreadKiSelectReadyThread(0Prcb);//調(diào)度處一個if(NextThread){}{}}
Prcb->CurrentThread=NextThread;NextThread->State=Running;InterlockedOr((PLONG)&KiIdleSummary,Prcb->SetMember);NextThread=Prcb->IdleThread;//使用空轉(zhuǎn)線程Prcb->CurrentThread=NextThread;NextThread->State=Running;WaitIrqlCurrentThread->WaitIrql;//記錄上次切出時的irqlApcState=KiSwapContext(CurrentThread,ifApcState)//切回來后,例行執(zhí)行內(nèi)核{KiDeliverApc(KernelMode,NULL,NULL);ASSERT(WaitIrql==PASSIVE_LEVEL);}WaitStatusCurrentThread->WaitStatus;//關(guān)鍵。返回該線程上次喚醒的原因returnWaitStatus;}INPVOIDObject[],//等待對INWAIT_TYPEWaitType,//WaitAll/AitAnyINKWAIT_REASONWaitReason,//上次切換原因INKPROCESSOR_MODEWaitMode,//來自用戶模式/內(nèi)核模式的等待請求INBOOLEertable,//本次等待是否可提醒(指是否可被強制喚醒)INPLARGE_INTEGERTimeoutOPTIONAL,//超時OUTPKWAIT_BLOCKWaitBlockArrayOPTIONAL)//等待塊數(shù){PKWAIT_BLOCKPKTHREADThread=PKWAIT_BLOCKTimerBlock&Thread->WaitBlock[TIMER_WAIT_BLOCK];//定時器等待塊是固定的PKTIMERTimer=&Thread->Timer;NTSTATUSWaitStatus=BOOLEANPLARGE_INTEGEROriginalDueTime=Timeout;LARGE_INTEGERDueTime,NewDueTime,InterruptTime;ULONGIndex,Hand=0;WaitBlockArray=&Thread->WaitBlock[0];ifThread->WaitNextgotoWaitStart;//首輪循環(huán)從WaitStart處開始Thread->WaitNext=FALSE;for(;;){{{Thread->Preempted=if((Thread->ApcState.KernelApcPending)&&!(Thread->SpecialApcDisable)&&(Thread->WaitIrql<APC_LEVEL)){}{
Index=if(WaitType=={{CurrentObject=if(CurrentObject->Header.Type=={if((CurrentObject->Header.SignalState>0)||(Thread==CurrentObject->OwnerThread)){if(CurrentObject->Header.SignalState!={}{}}}
KiSatisfyMutantWait(CurrentObject,Thread);WaitStatus=Thread->WaitStatus|Index;gotoDontWait;//只要滿足一個就退出函數(shù)elseif(CurrentObject->Header.SignalState>{WaitStatus=Index;}}while(Index<}Else{CurrentObject=if(CurrentObject->Header.Type=={if((Thread==CurrentObject->OwnerThread)&&(CurrentObject->Header.SignalState==(LONG)MINLONG)){}elseif((CurrentObject->Header.SignalState<=0)&&(Thread!=CurrentObject->OwnerThread)){}}elseif(CurrentObject->Header.SignalState<={//}}while(Index<if(IndexCount)//if所有對象都有信號{WaitBlock=WaitBlockArray;{CurrentObject=(PKMUTANT)WaitBlock->Object;KiSatisfyObjectWait(CurrentObject,Thread);WaitBlock=WaitBlock->NextWaitBlock;}while(WaitBlock!=WaitStatusThread->WaitStatus;//喚醒原因為‘真喚醒’類型gotoDontWait;}}WaitStatus=KiCheckAlertability(Thread,Alertable,WaitMode);if(WaitStatus!=STATUS_WAIT_0)break;if{InterruptTime.QuadPart=if((ULONGLONG)InterruptTime.QuadPart>=Timer-WaitStatus=STATUS_TIMEOUT;gotoDontWait;}Timer->Header.Inserted=TRUE;WaitBlock->NextWaitBlock=TimerBlock;}WaitBlock=WaitBlockArray;{CurrentObject=WaitBlock-WaitBlock=WaitBlock->NextWaitBlock;}while(WaitBlock!=if(Thread->Queue)KiActivateWaiterQueue(Thread->Queue);Thread->State=Waiting;KiAddThreadToWaitList(Thread,Swappable);if}
WaitStatus=KiSwapThread(Thread,喚醒原if(WaitStatus!=STATUS_KERNEL_APC)returnif(Timeout)Timeout=Thread->WaitIrql=KeRaiseIrqlToSynchLevel();}returnWaitStatus;return}#defineThread->WaitBlockList=WaitBlockArray;Index=0;{WaitBlock=&WaitBlockArray[Index];WaitBlock->Object=Object[Index];WaitBlock->WaitKey(USHORT)Index;//關(guān)鍵WaitBlock->WaitTypeWaitType;//所有等待塊的等待類型都相同WaitBlock->Thread=Thread;WaitBlock->NextWaitBlock=&WaitBlockArray[Index+1];}while(Index<WaitBlock->NextWaitBlockWaitBlockArray;單循環(huán)鏈表Thread->WaitStatus=STATUS_WAIT_0;if{TimerBlock->NextWaitBlock=WaitBlockArray;KxSetTimerForThreadWait(Timer,*Timeout,&Hand);DueTime.QuadPart=Timer->DueTime.QuadPart;}Thread->AlertableAlertable;//是否可被強制喚Thread->WaitModeWaitMode;//來自用戶模式/內(nèi)核模式的等待請求Thread->WaitReason=WaitReason;//上次被切原因Thread->WaitListEntry.Flink=Swappable=KiCheckThreadStackSwap(Thread,typedefstructDISPATCHER_HEADERHeader;//公共頭部LONGLimit;//信號量的最大信號個}KSEMAPHORE,NtCreateSemaphore(OUTPHANDLESemaphoreHandle,//返回信號量對象的句柄INACCESS_MASKDesiredAccess,INPOBJECT_ATTRIBUTESObjectAttributesOPTIONAL,//信號量的名稱及其他屬性INLONGInitialCount,//信號量的初始信號個數(shù)INLONGumCount)//支持的最大信號個{HANDLEKPROCESSOR_MODEPreviousMode=ExGetPreviousMode();NTSTATUSStatus;if(PreviousMode!={{}{_SEH2_YIELD(return}}if((umCount<=0)||(InitialCount<0)||(InitialCount>umCount))returnSTATUS_INVALID_PARAMETER;NULL,sizeof(KSEMAPHORE),0,0,(PVOID*)&Semaphore);if{ Status=ObInsertObject((PVOID)Semaphore,NULL,DesiredAccess,0,NULL,&hSemaphore);if(NT_SUCCESS(Status)){{*SemaphoreHandle=}{Status=}}}return}KeInitializeSemaphore(INPKSEMAPHORESemaphore,INLONGCount,INLONG{sizeof(KSEMAPHORE)/Semaphore->Limit=}#defineKeInitializeDispatcherHeader(Header,t,s, (Header)->Type= (Header)->Absolute= (Header)->Size= (Header)->Inserted= (Header)->SignalState=State;//初始信號個數(shù) }當(dāng)SignalState減到0時,就需要等待其他線程釋放信號量。NtReleaseSemaphore(INHANDLEINLONGReleaseCount,//一次可以釋放多個信號量,這將一次喚醒多個線程OUTPLONGPreviousCountOPTIONAL)//返回之前的信號個數(shù){KPROCESSOR_MODEPreviousMode=ExGetPreviousMode();PKSEMAPHORESemaphore;NTSTATUSif((PreviousCount)&&(PreviousMode!={{}{_SEH2_YIELD(return}}if(ReleaseCount<=returnStatus=if{
{LONGPrevCount=if(PreviousCount)*PreviousCount=PrevCount;}{Status=}}return}KeReleaseSemaphore(INPKSEMAPHOREINKPRIORITYIncrement,//優(yōu)先級增INBOOLEAN{LONGInitialState,State;KIRQLOldIrql;PKTHREADCurrentThread;OldIrql=InitialState=Semaphore->Header.SignalState;StateInitialStateAdjustment;//一次增加N個信號if((Semaphore->Limit<State)||Adjustment<0)){}Semaphore->Header.SignalState=if(!(InitialState)&&!(IsListEmpty(&Semaphore->Header.WaitListHead)))KiWaitTest(&Semaphore->Header,Increment);if(Wait==FALSE){}
CurrentThread=KeGetCurrentThread();CurrentThread->WaitNext=TRUE;CurrentThread->WaitIrql=OldIrql;return}用typedefstruct_KMUTANT{struct_KTHREAD*RESTRICTED_POINTEROwnerThread;//關(guān)鍵。當(dāng)前擁有者線程BOOLEANAbandoned;//是否被擁有者線程因意外終止而拋棄了}KMUTANT,*PKMUTANT,KMUTEX,*PKMUTEX;KeInitializeMutant(INPKMUTANT{KIRQLOldIrql;if{}
CurrentThread=KeGetCurrentThread();Mutant->OwnerThreadCurrentThread;//看OldIrql=KiAcquireDispatcherLock();Mutant->OwnerThread=sizeof(KMUTANT)/InitialOwner01);//初始對外信號個數(shù)為0或者Mutant->Abandoned=Mutant->ApcDisable=}NtReleaseMutant(INHANDLEINPLONGPreviousCount{PKMUTANTKPROCESSOR_MODEPreviousMode=ExGetPreviousMode();NTSTATUSStatus;if((PreviousCount)&&(PreviousMode!={{}{_SEH2_YIELD(return}}Status=PreviousMode,if{{LONGPrev=KeReleaseMutant(Mutant,MUTANT_INCREMENT,FALSE,FALSE);if(PreviousCount)*PreviousCount=Prev;}{Status=}}return}KeReleaseMutant(INPKMUTANTINKPRIORITYINBOOLEANAbandon,//是否是因為線程意外終止而拋棄的INBOOLEANWait){KIRQLOldIrql;PKTHREADCurrentThread=KeGetCurrentThread();BOOLEANEnableApc=FALSE;OldIrql=PreviousStateMutant->Header.SignalState;//先前的擁有計數(shù)if(Abandon==FALSE)//最典型{if(Mutant->OwnerThread!={ExRaiseStatus(Mutant->Abandoned?STATUS_ABANDONED}}{}
Mutant->Header.SignalState1;//復(fù)位成1,表示直接對外有信號Mutant->Abandoned=TRUE;//標記為被擁有者線程意外拋棄了if(Mutant->Header.SignalState1)//如果該互斥對象變得對其他線程可用{ifPreviousState0)//若是正常釋放的互斥對象(非意外終止原因{EnableApc=Mutant->ApcDisable;}Mutant->OwnerThreadNULL不再有擁有者線程了ifIsListEmpty(&Mutant-,}if(Wait==FALSE){}
CurrentThread->WaitNext=TRUE;CurrentThread->WaitIrql=OldIrql;if(EnableApc)KeLeaveCriticalRegion();returnPreviousState;}層的WaiFor操作就會一直阻塞,等待外層的WaitFor操作釋放互斥對象,這樣就會死鎖。KeSetEvent(INPKEVENTINKPRIORITYIncrement,INBOOLEANWait){KIRQLOldIrql;PKTHREADThread;{return}OldIrql=KiAcquireDispatcherLock();PreviousState=Event->Header.SignalState;Event->Header.SignalState1;//置為有信號狀(!(!({if(Event->Header.TypeEventNotificationObject)醒所有正在等待的線KxUnwaitThread(&Event->Header,Increment);KxUnwaitThreadForEvent(Event,}if{Thread=KeGetCurrentThread();Thread->WaitNext=TRUE;Thread->WaitIrql=OldIrql;}return}LONGKeResetEvent(INPKEVENT{KIRQLLONGPreviousState;OldIrql=KiAcquireDispatcherLock();PreviousState=Event->Header.SignalState;Event->Header.SignalState0;//復(fù)位成無信號狀態(tài)return}#define*(OldIrql)= 義為unsignedint64。VOIDKeInitializeSpinLock(outPKSPIN_LOCKSpinLock{*SpinLock=}INPKSPIN_LOCKOUTPKIRQL);INPKSPIN_LOCKINKIRQL *(OldIrql)= 翻forceinlineKeAcquireSpinLockRaiseToDpc(inoutPKSPIN_LOCK{KIRQLOldIr
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 工作總結(jié)之高中數(shù)學(xué)社團活動總結(jié)
- 電工電子技術(shù)(第3版) 課件 1.8.2 戴維南定理
- 銀行員工行為規(guī)范與紀律制度
- 《俞慧紅樓夢》課件
- 《設(shè)計模板》課件
- 《銀行入職培訓(xùn)課件》課件
- 《放射性監(jiān)測》課件
- 《教育的構(gòu)成》課件
- 分式的性質(zhì)課件
- 2024屆高考語文一輪復(fù)習(xí)第2章小說閱讀4第三節(jié)分析環(huán)境描寫-聚焦人物讀懂風(fēng)景課件
- 國家開放大學(xué)《財務(wù)管理》章節(jié)隨學(xué)隨練參考答案
- abap--一個功能非常全面的增強出口查找工具(僅供學(xué)習(xí))
- 服裝工藝(各工序)單價表
- 隧道變形及其控制技術(shù)1
- 生命密碼流年
- 紫色系簡潔風(fēng)送貨單表格模板
- 機械加工切削參數(shù)匯總
- 施工單位組織機構(gòu)圖(共3頁)
- 關(guān)鍵工序、特殊工序識別
- 腳手架巡查記錄表
- 年產(chǎn)4萬噸鋁板生產(chǎn)項目建議書寫作模板-立項申批
評論
0/150
提交評論