青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

麒麟子

~~

導(dǎo)航

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

統(tǒng)計(jì)

常用鏈接

留言簿(12)

隨筆分類

隨筆檔案

Friends

WebSites

積分與排名

最新隨筆

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

#

告一段落

今天做完了光照提交,被法線問題狠狠地糾結(jié)了兩個(gè)小時(shí)。現(xiàn)在想來,自己真是很2.

材質(zhì)系統(tǒng)雛形算是有了,支持FPP和SHADER、材質(zhì)動(dòng)畫、XML加載。算下來,這系統(tǒng)也做得夠久了,把所有時(shí)間算起來,估計(jì)也有6人*月的樣子。

反復(fù)修改好幾次,這次算是在使用上有點(diǎn)長進(jìn)。其間也收集了不少值得注意的問題。 這些問題在OGRE,Torque等源碼里都有所注釋,感覺開源代碼最大的好處就是注釋完整。比許多家釀的東西要好。(至少好認(rèn)。。。)

隨筆記錄的一些注意事項(xiàng),貼在此處以備忘

在D3D和SM1中.常量總是會(huì)被打包成4元素大小.
因此. 在SM1中.我們只能使用INT4或FLOAT4的設(shè)置方式.

在HLSL中.如果使用了結(jié)構(gòu)體.則結(jié)構(gòu)體會(huì)進(jìn)行對(duì)齊操作.就像
VS中的#pragma pack 4一樣.

GPU中的常量總是保持在最后一次SetXXConstantsX時(shí)的值.但D3D8例外.若D3D8程序中使用了DEF定義常量.則依然保持DEF值.因而會(huì)造成不可預(yù)測(cè)的值出現(xiàn).

將常量打包,然后用SetXXConstantX方式提交數(shù)據(jù). 即減少API CALLS次數(shù).理論上會(huì)提高程序效率.GAME DEV.NET上一老外的程序提升45%左右. 而具體情況待測(cè).

DX8的SHADER在設(shè)備丟失后,必須重建.因此需保存其MicroCode以使重建時(shí)更快.而DX9的卻不需要.


"When rendering using vertex shaders, each stage's texture coordinate index must be set to its default value." DX9 as followed.

  for (unsigned int nStage=0; nStage < 8; ++nStage)
   __SetTextureStageState(nStage, D3DTSS_TEXCOORDINDEX, nStage);

Something  about the color_op and alpha_op must be kept IN MIND.
Disables output from this texture stage and all stages with a higher index. To disable texture mapping, set this as the color operation for the first texture stage (stage 0). Alpha operations cannot be disabled when color operations are enabled. Setting the alpha operation to D3DTOP_DISABLE when color
blending is enabled causes undefined behavior

當(dāng)可編程管線啟用時(shí),Stage:0 D3DRS_TRANSFORMFLAGS 必須為0.

對(duì)于FFP來說,如果紋理為空,則僅繪制當(dāng)前模型。對(duì)于VS和PS來說,如果需要紋理,但紋理為空,則什么都不做。

世界矩陣和觀察矩陣會(huì)對(duì)法線進(jìn)行轉(zhuǎn)換,導(dǎo)致法線長度產(chǎn)生變化,(特別是矩陣帶有縮放的情況)。從而會(huì)引起光照計(jì)算不正確。 D3DRS_NORMALIZENORMALS == TRUE 可以解決這個(gè)問題,但開銷是巨大的。 因此盡量避免使用,以及不要對(duì)模型進(jìn)行縮放變換。可編程管線可無視此標(biāo)志。

本來說插個(gè)圖的,可惜這機(jī)器上沒裝客戶端,插圖很不便。省了。。。。

posted @ 2013-02-22 22:33 麒麟子 閱讀(228) | 評(píng)論 (0)編輯 收藏

Making RTS games

Reference to:
Where to start for RTS games?
Making RTS games,and etc.

----------------------------------------------------------------------------
3D
Glest
Glest is a 3D real-time strategy game. Fully customizable using XML and a set of tools.SF 
My compile steps is here 

TA Spring 
an open source project developing a new realtime strategy game.
Here is the detail.
The screen shots are great!
Here is the  chinese players froum.

warzone2100
http://wz2100.net/home 
3d rts game.
My compile steps is here 

2D
dark oberon
http://dark-oberon.sourceforge.net/?page=documentation 
2D rts game base on glew.The lastest version is 1.0.2. Easy to compile in vc6.


Stratagus 
Stratagus comes from FreeCraft ( see here )
A free 3D RTS engine used by several games. The developers of Stratagus are working on Boswar(2D), which is an open source  RTS game using  Startagus.

machinations
http://machinations.sourceforge.net/index.php 
http://www.machrts.com/ 
It was made using GLFW, a framework for OpenGL. it's an open-source rts using openGl. with that, tutorials, and practice, you should get yours to work .
i had port machinations v0.34 from Borland IDE to VC2005,see here 

ORTS
a RTS engine

RTS Starter Kit (Indie License)
Torque Game Engine                       
The only RTS maker that exists is the RTS Starter Kit (Indie License) to be used with the Torque Game Engine. It will cost a total of $100(engine) + $50(addon) though.


OpenRTS 
OpenRTS is an open source realtime strategy game.Written in Python.

WIKI :
OpenRTS 
TA_Spring 

編譯運(yùn)行了某些游戲,發(fā)現(xiàn): 
3D方面Glest, TA spring, warzone2100的效果不錯(cuò).
2D方面dark oberon似乎不錯(cuò),畢竟版本已經(jīng)1.0以上了。
網(wǎng)絡(luò)上對(duì)Bos war的引擎評(píng)價(jià)似乎不錯(cuò)。

 

 

------------------------------------------------------------------------------------------------------------------

個(gè)人愚見:其實(shí) 0 A.D.不錯(cuò)

posted @ 2013-02-22 22:32 麒麟子 閱讀(407) | 評(píng)論 (0)編輯 收藏

【Unity3d】3d網(wǎng)頁游戲場(chǎng)景打包與加載

http://www.mysjtu.com/page/M0/S716/716482.html

 

3d游戲中 一個(gè)場(chǎng)景往往斗勁大 若是游戲的進(jìn)行須要下載一個(gè)10M甚至更大的場(chǎng)景時(shí) 加載所用的時(shí)候會(huì)導(dǎo)致很大項(xiàng)目組玩家的流失

我們知道unity3d中的內(nèi)置地形是應(yīng)用一張高度圖 對(duì)其地形進(jìn)行打包今后 發(fā)明<=100KB

那么若是采取unity3d的內(nèi)置地形作為游戲中的地形時(shí) 起首加載地形并顯示 再去加載場(chǎng)景中的部件(比如樹、房子等) 將會(huì)很有須要

在加載場(chǎng)景中的部件時(shí) 可以按照玩家當(dāng)前地點(diǎn)的地位 由近到遠(yuǎn)的去加載

場(chǎng)景中的每個(gè)部件實(shí)際上并不都是獨(dú)一無二的

比如一棵一模一樣的樹 可能同一個(gè)場(chǎng)景中呈如今很多處所 不合的只是樹的地位信息

那么在加載場(chǎng)景的時(shí)辰則只須要加載一個(gè)樹的模型 并記錄下N個(gè)樹的transform信息 將會(huì)大大的削減場(chǎng)景所占的空間

若是模型的重用率較高 那么這個(gè)題目的解決將會(huì)成倍的削減一個(gè)場(chǎng)景所占的空間

場(chǎng)景在加載時(shí) 也只須要下載一個(gè)樹的模型 并按照transform信息 在指定的地位復(fù)制出N棵樹即可

在應(yīng)用unity3d的BuildPipeline進(jìn)行打包之前 須要遍歷一邊所選文件夾下的場(chǎng)景文件

若是文件的MeshFilter的Mesh為在該文件夾中只呈現(xiàn)了一次 則申明該模型在場(chǎng)景中沒有反復(fù) 則記錄下該模型文件的transform信息 并打包

若是該Mesh呈現(xiàn)的次數(shù)大于一次 則記錄下這些和該Mesh雷同的模型的transform信息 打包時(shí)包含一個(gè)模型和多個(gè)transform信息

在unity3d中有個(gè)名為ScriptableObject的類 可以哄騙它來存儲(chǔ)本身所需的各類百般的資料

public class TransformHolder : ScriptableObject
{
public int Length;
public Vector3[] position;
public Quaternion[] eulerAngles;
public Vector3[] localScale;
}

如許一來 每一個(gè)資料包中都包含一個(gè)模型和一個(gè)TransformHolder類型的文件
TransformHolder的Length若為1 則申明該模型在場(chǎng)景中只呈現(xiàn)了一次

若大于1 則可以按照記錄的transform信息輪回生成多個(gè)

本來有幾百個(gè)資料包 大小有十幾兆的場(chǎng)景

用該辦法后 變成了二十多個(gè)資料包 大小削減到不足2M

當(dāng)然這實(shí)用于場(chǎng)景中的模型有重用的現(xiàn)象

posted @ 2013-02-22 22:29 麒麟子 閱讀(1220) | 評(píng)論 (0)編輯 收藏

Nt vs. Zw - Clearing Confusion On The Native API

The NT native API is nothing new. It’s been discussed ad nauseum, it’s been exploited by umpteen different utilities, and portions of it have even migrated into the realm of the fully documented and supported in the DDK. Come to think of it, why am I even writing about this then? I think I will just pop in my Kung Faux DVD and watch the Ill Master take care of business…Oh yeah, now I remember why I started writing this: Believe it or not, people are still confused about certain aspects of the native API. Common questions include:

 

  • Why are there two flavors, NtXxx and ZwXxx?
  • Why do my calls to ZwXxx sometimes fail, but sometimes work?
  • What does the Zw stand for? Was the name of the original NT developer really Zimbanza Woobie!?

OK, well, maybe people don’t really ask that last one very often. But for those that do, Zw is entirely random and the developers chose it specifically because it could never mean anything. The other questions do often come up on the NTDEV and NTFSD mailing lists though (see http://www.osronline.com/lists for more info on the NTDEV and NTFSD peer help lists), so it is about time the record was set straight. In order to do this we are going to do a bit of disassembly. All listings will be from an XP SP1 Free build. Also, note that we’ve got sample driver code to accompany this article that shows you how to use the native system services from Kernel Mode. See the description (and URL) of the sample code provided at the end of this article.

This article assumes that the reader already understands that there is a native API and understands how the native API relates to the other subsystems in Windows. Enough information already exists on this out there that it is not worth repeating in this article.

Vanilla or Chocolate

First, let’s do a bit of math that even I can handle. We have two sets of APIs, NtXxx and ZwXxx, and two modes to call them from, User and Kernel. This means that we have four different scenarios under which we can call these routines. Using XxReadFile as the example, we have:

  • User Mode application calls NtReadFile
  • User Mode application calls ZwReadFile
  • Kernel Mode driver calls NtReadFile
  • Kernel Mode driver calls ZwReadFile

What exactly are the differences in these scenarios? Let us start by talking about the land where no driver writer feels safe, User Mode.

Calling From User Mode

As you (probably) know, User Mode applications link with NTDLL.LIB. Sticking with our example of XxReadFile, let’s compare the disassembly of the NtReadFile and ZwReadFile routines within NTDLL:

0: kd> u ntdll!NtReadFile
ntdll!NtReadFile:
77f761e8 b8b7000000       mov     eax,0xb7
77f761ed ba0003fe7f       mov     edx,0x7ffe0300
77f761f2 ffd2             call    edx
77f761f4 c22400           ret     0x24


 

That looks to me to be a stub that calls another routine and returns. Further inspection will definitely be necessary, but let’s just check out ZwReadFile before we move on.

0: kd> u ntdll!ZwReadFile
ntdll!NtReadFile:
77f761e8 b8b7000000       mov     eax,0xb7
77f761ed ba0003fe7f       mov     edx,0x7ffe0300
77f761f2 ffd2             call    edx
77f761f4 c22400           ret     0x24

Well look at that! They both point to the exact same place, which means that from a User Mode program it does not matter which routine you call because you are going to end up in the same place anyway. If you pick any other system service call you will notice that they all have this exact format, so our example will apply to any API you choose. The good news is that this article just got a bit shorter and I’ll be chillin’ with the Ill Master in less time than I thought.

Now let’s see what exactly is at address 0x7ffe0300, which is where we jump when we make these calls (and, as mentioned previously, where we jump when we make any native API call from User Mode).

0: kd> ln 0x7ffe0300
(7ffe0300)   SharedUserData!SystemCallStub  
Exact matches:
    SharedUserData!SystemCallStub

0: kd> u SharedUserData!SystemCallStub
SharedUserData!SystemCallStub:
7ffe0300 8bd4             mov     edx,esp
7ffe0302 0f34             sysenter
7ffe0304 c3               ret

Now how’s that for a straight-forward routine: Something (turns out it’s the code that represents which system service was called) gets put into EAX by the caller, then this routine puts a pointer to the top of the User Mode stack into EDX. Ohh, SYSENTER, uhm, ah, of course…Must be a new instruction. Let me see, that was added in…1997?? Forging ever onward, let us check the Intel documentation for SYSENTER. It says here that the SYSENTER instruction switches the current thread into Kernel Mode and executes the routine pointed to by the SYSENTER_EIP_MSR, which is MSR 0x176.

This is a good time to point out why hooking INT 2E is a bad idea and why old INT 2E hooks will not work. On systems that support SYSENTER, INT 2E is simply not used anymore. Your hook is useless if no one is ever going to call it!

Going back to WinDBG, let us execute the rdmsr command and see what is in the SYSENTER_EIP_MSR:

0: kd> rdmsr 176
msr[176] = 00000000:8053a270

Very interesting. Let’s see what that address is:

0: kd> ln 8053a270
(8053a270)   nt!KiFastCallEntry   |  (8053a2fb)   nt!KiSystemService
Exact matches:
    nt!KiFastCallEntry

I will spare all of you the disassembly of KiFastCallEntry. It is an interesting read so I suggest it if you are curious, but all the code is going to do is build a trap frame so that when we exit Kernel Mode we can continue executing from where we left off. I will show the very last line of the function though:

053a2f9 eb5c jmp     nt!KiSystemService+0x5c (8053a357)

We can see here that KiFastCallEntry does not actually return, it just does an unconditional jump to some offset into KiSystemService. Again sparing the reader large amounts of disassembly, the code in KiSystemService eventually takes the service number that was put into EAX on the first line of the call to XxReadFile and looks up its entry in the system service table, KiServiceTable. Each entry in this table is a pointer to a native API, also known as "system service", routine. Before calling the "system service" routine, the system service dispatch code copies the parameters that are being passed to the system service from the top of the User stack to the top of the Kernel stack. Ah! Guess that’s why a pointer to the top of the stack is saved into EDX before executing the SYSENTER.

Using the debugger extension DLL accompanying this article, we can see that index 0xb7 points to the kernel version of NtReadFile:

0: kd> !osrexts.sst
0: 0x805912c2  (nt!NtAcceptConnectPort)
1: 0x805d87b0  (nt!NtAccessCheck)
2: 0x805dc3e4  (nt!NtAccessCheckAndAuditAlarm)
...
b7: 0x8056b2ec  (nt!NtReadFile)
...

And, if we look at the address of nt!NtReadFile (address 0x8056b2ec), we see:

0: kd> u nt!NtReadFile
nt!NtReadFile:
8056b2ec 6a58             push    0x58
8056b2ee 6858044e80       push    0x804e0458
8056b2f3 e8e09ffcff       call    nt!_SEH_prolog (805352d8)
8056b2f8 33ff             xor     edi,edi
8056b2fa 897de4           mov     [ebp-0x1c],edi
8056b2fd 897de0           mov     [ebp-0x20],edi
8056b300 897dd8           mov     [ebp-0x28],edi
8056b303 897ddc           mov     [ebp-0x24],edi
8056b306 64a124010000     mov     eax,fs:[00000124]
8056b30c 8945d4           mov     [ebp-0x2c],eax
8056b30f 8a8040010000     mov     al,[eax+0x140]
8056b315 8845d0           mov     [ebp-0x30],al
8056b318 57               push    edi
8056b319 8d45cc           lea     eax,[ebp-0x34]
8056b31c 50               push    eax
8056b31d ff75d0           push    dword ptr [ebp-0x30]

Ah, Finally! It looks like the function that actually implements the read file system service.

So, to summarize the flow of a native API call from User Mode

User Mode program calls either NtXxx or ZwXxx, both of which point to the same location

All native API calls from User Mode have a body that simply loads an index into EAX, executes SystemCallStub, and returns

SystemCallStub saves a pointer to the top of the User Mode stack into EDX and executes a SYSENTER instruction

SYSENTER disables interrupts, switches the thread into Kernel Mode and executes the instruction located in the SYSENTER_EIP_MSR (which on XP SP1 is KiFastCallEntry)

KiFastCallEntry builds a trap frame so it knows where to go when returning back to User Mode, enables interrupts, and jumps into KiSystemService

KiSystemService, amongst doing other things, copies the parameters from the User stack (pointed to by EDX) and takes the value previously stored in EAX and executes the function located at KiServiceTable[EAX]

The native API now executes in Kernel Mode with the previous mode of the thread set to User Mode. This indicates the caller came from User Mode. If you are going to remember one thing about this exercise, remember this! We’ll talk about it much more later in this article.

Now that we have gone through a gross amount of detail for the User Mode portion, we should be able to zip right through the Kernel Mode variants.

Calling From Kernel Mode

As you (should) know, Kernel Mode components link with NTOSKRNL.LIB. Let’s continue to use XxReadFile and see what the two variants look like from the kernel side of things. First, let’s try NtReadFile:

0: kd> u nt!NtReadFile
nt!NtReadFile:
8056b2ec 6a58             push    0x58
8056b2ee 6858044e80       push    0x804e0458
8056b2f3 e8e09ffcff       call    nt!_SEH_prolog (805352d8)
8056b2f8 33ff             xor     edi,edi
...

Well, this looks familiar! It’s the function that implements NtReadFile that was eventually called from User Mode (because it is where the system service table points to). Therefore, notice that if we call NtReadFile from a driver, we just execute the function, bypassing any common system service dispatcher type of entry point.

Going on what I have seen before in User Mode, where NtXxxx and ZwXxxx were identical, when I disassemble nt!ZwReadFile I’d probably expect to see exactly what I saw in nt!NtReadFile. Let’s check:

0: kd> u nt!ZwReadFile
nt!ZwReadFile:
80504d4c b8b7000000       mov     eax,0xb7
80504d51 8d542404         lea     edx,[esp+0x4]
80504d55 9c               pushfd
80504d56 6a08             push    0x8
80504d58 e89e550300       call    nt!KiSystemService (8053a2fb)
80504d5d c22400           ret     0x24

Blast! I guess I have got a bit longer before I can lounge.

We see a familiar instruction in the beginning, move 0xb7 into EAX. Then we put a pointer to the parameters that appear on the Kernel stack into EDX, push the EFLAGS and a constant value onto the stack, and finally call KiSystemService!? That was the function that we wound-up calling from KiFastCallEntry when we did the SYSENTER from User Mode.

So why aren’t we executing a SYSENTER here? Duh! Because we are already in Kernel Mode, so what is the point of entering it again? The most important thing that is going to happen when we go this route is that we are going to call the native API from Kernel Mode, execute in Kernel Mode, and in the course of going through KiSystemService our previous mode will be set to Kernel Mode. Note that this is definitely not the case if we just call the NtXxx version from Kernel Mode. In that case, our previous mode stays untouched and we go right to the function and start executing.

So, to summarize the flow of a native API call from Kernel Mode:

Case A:

  • Kernel Mode component calls NtXxx
  • This is a direct call to the function that implements the system service. The call does not change previous mode.

Case B:

  • Kernel Mode component calls ZwXxxx
  • This leads to a step that puts the system service code (index value) into EAX, and a pointer to the arguments that have already been pushed onto the (Kernel Mode) stack into EDX.
  • Then calls KiSystemService, which amongst doing other things, copies the parameters from the location pointed to by EDX and takes the value previously stored in EAX and executes the function located at KiServiceTable[EAX].
  • The native API now executes (still in Kernel Mode) with the previous mode set to Kernel Mode. This indicates the caller came from Kernel Mode.

So, it’s clear that calling NtXxx directly has less overhead, but calling ZwXxxx changes previous mode. So, what’s up with that? It seems like previous mode must be something pretty important.

Previous Mode

Time to step back and figure out what all of this means. An important fact to know is that Kernel Mode components by default trust all other Kernel Mode components. Because system services are always processed in Kernel Mode, Windows keeps track of whether the request originated from User Mode or Kernel Mode to determine if the caller is to be implicitly trusted. The system uses the previous mode indicator to determine the mode from which a system service call came. When a call comes from User Mode, previous mode is set to User. When a system service processing routine needs to determine whether or not to implicitly trust its caller, it checks the value of previous mode. If previous mode is set to User, the system service processing routine knows the call came from User Mode and thus any parameters passed in to the function need to be validated before they can be used.

This is why the previous mode being set is really the most important part about what we have talked about so far. No matter what a User Mode application does, the system treats its system service request as a User request, coming from User Mode, and goes out of its way to validate the request. All buffers are subject to validation, all access checks are performed, and absolutely no part of the request is implicitly trusted. However, a Kernel Mode request is not as scrutinized and it is assumed that the passed in parameters are valid.

If a Kernel component calls the ZwXxx version of a native API, all is well. The previous mode is set to Kernel and the credentials of the Kernel are used. The system service processing routine that is called assumes that any parameters that are passed are valid, because the request came from a Kernel Mode component (and Kernel Mode components implicitly trust each other).

The NtXxxx version of the native system service is the name of the function itself. Thus, when a Kernel Mode component calls the NtXxxx version of the system service, whatever is presently set into previous mode is unchanged. Thus, it is quite possible that the Kernel component could be running on an arbitrary User stack, with the requestor mode set to User. The system service will not know any better, attempt to validate the request parameters, possibly using the credentials of the arbitrary User Mode thread, and thus possibly fail the request. Another problem here is that one step in the validation process for a User Mode request is that all passed in buffers have either ProbeForRead or ProbeForWrite executed on them, depending on the buffer’s usage. These routines raise exceptions if executed on Kernel Mode addresses. Therefore, if you pass in Kernel Mode buffers with your request mode set to User, your calls into the native API return STATUS_ACCESS_VIOLATION.

The moral of this bedtime story is that if you are in User Mode, use whatever variant you think makes your code look pretty. In Kernel Mode, use the ZwXxx routines and get your previous mode set properly, to Kernel Mode.

If I keep this up I am going to be seriously late for my date with Queenie, but she is just going to have to wait because there is still more to cover.

I’ll Handle This

All of the native API calls work with handle values, which index into one of two types of handle tables. A Handle either describes an entry in a table that is effectively a part of the EPROCESS structure (which means it describes an object that is specific to a particular process context) or it describes an entry in a global handle table (which means it describes an object that is visible to all process contexts). This makes for some interesting scenarios.

Say you have an existing driver and you decide that being able to optionally log to a file would be a nice feature. First thing you do is setup two IOCTLs, one to enable the logging and the other to disable the logging. In the handler for the IOCTL, to enable logging, you have the driver call ZwCreateFile (remember to use the Zw versions!), which returns you a handle to use to write to the file. So far so good.

InitializeObjectAttributes(&oa, &logFileName, OBJ_CASE_INSENSITIVE,
                NULL, NULL);

    code = ZwCreateFile(&devExt->LogFileHandle, GENERIC_WRITE,
     &oa, &iosb, NULL, FILE_ATTRIBUTE_NORMAL,
     0, FILE_OVERWRITE_IF,
     FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
     NULL, 0);

From here, you set up a flag in your device extension that indicates that you are logging to a file, and start to add calls to ZwWriteFile to all of your dispatch entry points.

      if (devExt->LoggingEnabled) {

        code = ZwWriteFile(devExt->LogFileHandle, NULL, NULL, NULL,
   &iosb, (PVOID)logMessage,
   logMessageLen),
   NULL, NULL);
   }

You note that a restriction of ZwWriteFile is that you must call it at PASSIVE_LEVEL, so you setup work items to log your timer DPC and DpcForIsr. Then you enable logging on your device and something weird happens. All of your calls to ZwWriteFile in your dispatch entry points succeed, but the ones in your work items return STATUS_INVALID_ HANDLE! How can a handle switch back and forth between being valid and invalid when you have done nothing but open it and write to it?

Remember that you created that handle in your dispatch entry point. Therefore, you could have been running in the process context of the calling application when you created that handle. In this case, your handle references an object in your User Mode application’s handle table, which is located via its EPROCESS. Your work items are running in the SYSTEM process context, so your call to ZwWriteFile is correctly failed with STATUS_INVALID_HANDLE. This is because the handle that you’re passing in is meaningless in the SYSTEM process’ context.

So what is the answer? Give up on Windows and start a revolution to bring back MULTICS? Luckily, it doesn’t have to come to that. There is already a built-in solution to this problem. All you need to do is specify OBJ_KERNEL_HANDLE as one of your object’s attributes and that handle will be good in any context you might end up calling it in. This flag is the cue to the Object Manager that you want the handle to go into the global handle table, making it visible in all process contexts.

InitializeObjectAttributes(&oa, &logFileName,
                  OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                  NULL, NULL);

Accompanying Samples

To see some of what we’ve talked about in action, this article has an accompanying sample for you to experiment with. The sample driver creates a log file in the root directory of the C: drive in response to an IOCTL. At the beginning of the main C file is a compile time flag USER_HANDLE. If this flag is not set, then the driver creates the handle as a Kernel Mode handle by using OBJ_KERNEL_HANDLE. Otherwise, the driver creates a User Mode handle that is valid only in the application’s context. The file is then written to using both NtWriteFile and ZwWriteFile from various parts of the driver. Each call has a full explanation of what NTSTATUS values we expect to be returned and why for both the User and Kernel handle cases. The driver portion of the sample is a legacy driver (non-WDM compliant) and must be installed with a utility such as OSR’s Driver Loader.

Also included in the samples download is a WinDBG extension DLL that locates the system service table and displays the system services located within it. To use it, simply put osrexts.dll into WinDBG’s extension DLL directory and execute !osrexts.sst in the command window.

In Summary

I hope that this article has finally put to rest the most common problems that people experience with the native API and cleared up the NtXxx versus ZwXxx question once and for all.

Now, where’s that DVD…

Related Articles
Going Native - Using the NT API for File I/O
OSR Press Comes Through Again: Classic NT Driver Book Now Available

User Comments
Rate this article and give us feedback. Do you find anything missing? Share your opinion with the community!
Post Your Comment

"Nt vs. Zw - Clearing Confusion On The Native API"
Nice article!!

Rating:
03-Dec-09, Netmonk Paul


"Native Mode vs. Native API"
I would like to know how to utilize these functions in Native Mode, I.E. like autochk does. I have tried using this example and use build to create a simple executable that will run from the BootExecute key of the session manager, like autochk, but i can't get it to build.

Rating:
02-Nov-05, Ketema Harris


"AMD64?"
Excelent article. Do you have any idea how these things are implemented in XP x64? The KiServiceTable doesn't seem to store pointers to functions. Or, maybe i got it wrong... Thanks.

Rating:
21-Jul-05, Marius Negrutiu


"In answer to the previous 2 comments"
Thanks to all for commenting...

In response to Ben Kial's post from 7 Jul 05, in which he says "only SOME of the kernel side NtXXX APIs are implemented in ntoskrnl.exe"

Sorry, but this is not correct. The functions might not be exported, but they are there. Specifically, I checked NtProtectVirtualMemory, and it is indeed in ntoskrnl.exe (it's part of the memory manager).

In response to Sean Park's comment from 8 Jul 05, in which he says "NtXxx functions expect user mode parameters... while ZwXxx functions are for kernel drivers."

Sorry, but this is not correct. The difference between the NT and ZW APIs is as stated in this article. This is not a topic about which we're GUESSING. We're giving you the definitively correct answers.

Peter

08-Jul-05, Peter Viscarola


"Not all NtXXX are in ntoskrnl.exe"
Very nice article! However, I found that only some of the kernel side NtXXX APIs are implemented in ntoskrnl.exe (or ntoskrnl.lib). For example, for API# 0x89

89: 0x80574045 (nt!NtProtectVirtualMemory)

it does not exit in ntoskrnl.exe. Does anybody know which .dll or .exe contain "nt!NtProtectVirtualMemory"?

Thanks,

Ben

Rating:
07-Jul-05, Ben Kial


"RE: What exactly is an MSR?"
An MSR is a "Model-Specific Register". That is, it's a register that's specific to a certain type of processor and it may or may not be available in previous or future versions of the processor. The entire list of Intel MSRs and the processors on which they're supported is in Appendix B of the Intel Architecture Software Developer's Manual: Volume 3.

04-Sep-03, Scott Noone


"What exactly is an MSR?"
I have one other question. You mention MSRs in your article. Try as I might, I have been unable to locate a concise explanation of what the heck they are. Can you point me to one (or, better yet, give me one). Thanks....

Dan

04-Sep-03, Dan Chernin


"RE: NTxxx functions from kernel mode"
Is there ANY time you want to call the NtXxxx variant from Kernel Mode? Well, yes. But it's typically unnecessarily risky.

Consider the case where (a) You know that you've been called directly from User Mode (so previous mode = user and current mode = kernel), and (b) You want to perform a request on behalf of the calling user. You want to use the user's access right, user's privileges, and you're passing arguments in that you received from user mode. In this case, you might call the NtXxxx variant of the function. This will cause the system service to perform checks and parameter validation just like the call came directly from the user.

I say this is unnecessary because you could just as easily -- and probably more securely -- performed those same checks within your driver before calling the ZwXxxx variant of the function.

What's MOST important is that you understand the difference between the two calls, and that you default to calling the ZwXxx variant unless you have some very specific reason why you want to call the NtXxx flavor.

04-Sep-03, Peter Viscarola


"NTxxx functions from kernel mode"
I guess my only question after reading this very good article is this: is there ever a situation where you WOULD call an NTxxx function directly? If not--as appears to be the case--what's the purpose of having the NTxxx symbol, aside from convenience?

Rating:
04-Sep-03, Dan Chernin

posted @ 2011-05-20 14:26 麒麟子 閱讀(1254) | 評(píng)論 (0)編輯 收藏

Deferred Shading

一直在關(guān)注這個(gè)東西,最近忙里偷閑,深入地了解了一下。 首先,我們說說延遲渲染的好處。畢竟一個(gè)東西的產(chǎn)生,是為了解決當(dāng)前已有的東西不能解決的問題。

image

Deferred Shading Tutorial下載

 

上面的文章很好地討論了采用傳統(tǒng)著色方案所需要面對(duì)的問題。主要是下面兩種情況。

image

image

 

而對(duì)于延遲著色的第一個(gè)好處,就是可以將光照處理對(duì)物體渲染的開銷由 M*N 變?yōu)?M+N (其中M為物體數(shù)目,N為光源數(shù)目)

image

 

延遲著色的一般框架圖如下:

image

 

image

image

 

image

image

image

 

延遲著色的好處

image

 

而延遲著色面臨的最大問題就是透明處理

image

 

另外,延遲著色主要得益于MRT(Multi Render Target).因?yàn)椋琈RT的限制即是延遲著色本身的限制,DX SDK DOC中有提到。

MSDN:http://msdn.microsoft.com/en-us/library/bb147221(v=vs.85).aspx

 

RenderMonkey中也有延遲著色例子。 我也用RenderMonkey重寫了一個(gè)自己的例子。

image 

OK, 完事兒!!!!

posted @ 2011-03-13 11:56 麒麟子 閱讀(2037) | 評(píng)論 (0)編輯 收藏

僅列出標(biāo)題
共38頁: First 7 8 9 10 11 12 13 14 15 Last 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲人成在线观看一区二区| 欧美日本亚洲视频| 国产精品久久久对白| 亚洲欧美日韩第一区| 久久精品理论片| 最新日韩精品| 亚洲欧美激情视频在线观看一区二区三区| 国产一区99| 亚洲激情网站免费观看| 国产精品一区二区久久国产| 国产真实乱子伦精品视频| 亚洲国产精品久久人人爱蜜臀| 欧美三级欧美一级| 免费成人网www| 国产精品稀缺呦系列在线| 欧美大尺度在线观看| 国产乱码精品一区二区三区不卡| 亚洲国产另类精品专区| 亚洲综合色噜噜狠狠| 在线观看成人av电影| 亚洲视频导航| 日韩视频在线观看一区二区| 欧美在线资源| 亚洲欧美精品suv| 欧美连裤袜在线视频| 久久视频国产精品免费视频在线 | 亚洲精品自在在线观看| 亚洲午夜国产成人av电影男同| 亚洲第一久久影院| 午夜视黄欧洲亚洲| 午夜伦欧美伦电影理论片| 欧美区一区二区三区| 欧美不卡福利| 狠狠狠色丁香婷婷综合久久五月| 亚洲一区中文| 亚洲一区区二区| 欧美日韩精品三区| 亚洲国产精品一区在线观看不卡| 国产综合视频在线观看| 亚洲欧美久久久| 欧美一区二区高清在线观看| 国产精品国产三级国产专播精品人| 亚洲精品中文字幕在线观看| 日韩一区二区精品葵司在线| 另类亚洲自拍| 欧美激情一区二区三区四区| 亚洲国产视频一区| 久久伊人亚洲| 欧美国产欧美综合 | 性感少妇一区| 欧美一区二区三区视频免费播放 | 91久久精品网| 一区二区欧美激情| 欧美日韩精品免费在线观看视频| 亚洲精品美女免费| 一区二区三区免费看| 欧美日韩一区二区视频在线观看| 亚洲美女免费精品视频在线观看| 一本大道久久a久久综合婷婷| 欧美乱在线观看| 一区二区精品在线观看| 亚洲一区亚洲二区| 国产精品女主播一区二区三区| 亚洲一区亚洲| 久久综合色播五月| 亚洲精品三级| 国产精品国产亚洲精品看不卡15| 午夜精品亚洲一区二区三区嫩草| 久久精品导航| 亚洲激情国产| 国产精品国产三级国产专播精品人| 亚洲欧美日韩国产一区二区三区| 久久久久久精| 最新成人av网站| 欧美性一区二区| 久久精品日韩欧美| 亚洲国产成人在线播放| 亚洲一区视频在线观看视频| 国产亚洲欧美一区二区| 免费成人高清在线视频| 中文国产成人精品| 老妇喷水一区二区三区| 99re8这里有精品热视频免费| 欧美午夜精彩| 麻豆成人在线播放| 亚洲视频在线一区| 韩日精品视频一区| 欧美久久久久久蜜桃| 午夜在线视频一区二区区别 | 国产亚洲精品bt天堂精选| 老司机午夜精品视频| 夜夜嗨av一区二区三区四季av| 欧美一二区视频| 亚洲美女免费视频| 国产一区二区激情| 欧美国产在线电影| 性视频1819p久久| 亚洲精品视频免费观看| 久久国产精品99国产| 日韩视频国产视频| 国模套图日韩精品一区二区| 欧美日韩精选| 久久一区二区精品| 亚洲欧美日本国产专区一区| 亚洲国产精品国自产拍av秋霞 | 国产精品久久久久久久久久久久久 | 免费中文字幕日韩欧美| 午夜精品久久久久久99热| 亚洲毛片一区| 亚洲大片在线| 久热精品在线视频| 午夜精品久久久久久久久久久久久| 亚洲精品久久久蜜桃| 国内外成人在线| 国产精品香蕉在线观看| 欧美午夜在线视频| 欧美久久综合| 免费日韩av| 毛片一区二区| 久久欧美肥婆一二区| 欧美资源在线| 亚洲欧美综合v| 亚洲永久视频| 一区二区三区视频在线播放| 亚洲精品黄色| 亚洲国产日本| 亚洲国产天堂久久国产91| 欧美成年网站| 老色鬼精品视频在线观看播放| 欧美在线观看网站| 欧美亚洲在线| 欧美在线播放高清精品| 欧美亚洲一级| 欧美一区二区三区精品电影| 亚洲新中文字幕| 中国av一区| 在线视频一区二区| 在线亚洲欧美专区二区| 亚洲天堂网站在线观看视频| 在线视频一区二区| 亚洲一区二区3| 亚洲在线一区二区三区| 亚洲欧美www| 性久久久久久久| 久久久久久9999| 欧美成人综合| 亚洲国产另类 国产精品国产免费| 欧美激情亚洲另类| 亚洲精品一区二区三区婷婷月| 夜夜嗨一区二区| 亚洲欧美日韩精品综合在线观看| 午夜欧美精品| 久久亚洲色图| 欧美日产国产成人免费图片| 欧美日韩一级黄| 国产麻豆精品久久一二三| 久久久91精品国产一区二区三区| 久久精品亚洲热| 欧美国产另类| 国产精品成人观看视频免费| 国产日韩亚洲欧美综合| 精品成人在线观看| 日韩一区二区高清| 欧美一区二区日韩| 免费91麻豆精品国产自产在线观看 | 欧美电影打屁股sp| 欧美人成网站| 国产欧美精品一区二区三区介绍| 国产有码在线一区二区视频| 亚洲欧洲在线看| 午夜精品久久久久99热蜜桃导演| 久久精品一区中文字幕| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲一区二区三区精品视频| 久久精品二区| 欧美成人国产va精品日本一级| 欧美精品亚洲精品| 国产精品毛片高清在线完整版| 国产欧美一区二区精品性| 激情五月综合色婷婷一区二区| 日韩视频欧美视频| 欧美在线关看| 亚洲日本在线观看| 小嫩嫩精品导航| 奶水喷射视频一区| 欧美四级电影网站| 在线播放视频一区| 亚洲欧美激情视频| 久久久水蜜桃av免费网站| 亚洲精品国产无天堂网2021| 午夜精品999| 欧美日韩国产一区二区三区| 国产自产女人91一区在线观看| 亚洲久久在线| 久久精视频免费在线久久完整在线看| 亚洲高清视频一区二区| 欧美在线看片| 欧美午夜精品久久久| 在线精品视频一区二区| 亚洲综合二区|