Archive

Archive for April, 2012

诡异的WriteFile和完成端口行为

April 6th, 2012 No comments

在写代码的过程中发现了一个很奇怪的现象。代码的主要意图是利用完成端口来获取写文件操作是否完成。

所以在判断了WriteFile的返回值以后,如果返回TRUE,就直接获取当前写入的字节。而如果返回值为FALSE,那么GetLastError() == ERROR_IO_PENDING的话等候完成端口的事件报告,并得到写入的字节数。 本来以为没有什么问题。但是测试的时候发现了一个问题。那就是即便WriteFile返回TRUE,并且写入字节数也和数据大小匹配,并且GetLastError() == 0. 但是完成端口那个地方仍然有事件报告,这个事件对我来说是一个未预期的事件。所以只能做如下判断

if( ( returnValue && GetLastError() == 0 ) ||
    (!returnValue && GetLastError() == ERROR_IO_PENDING) )
{
    //check IOCP event
}
else
{
    return err;
}

我现在的测试环境是WINXP+SP2,不知道其他的windows版本会有何表现

Categories: programming Tags: , ,

GetTickCount的实现

April 6th, 2012 No comments

昨天突然想看看GetTickCount的实现,于是借助调试器看了一下GetTickCount的汇编代码。那是一个相当的简单

_GetTickCount@0:
7C80934A mov edx,7FFE0000h
7C80934F mov eax,dword ptr [edx]
7C809351 mul eax,dword ptr [edx+4]
7C809354 shrd eax,edx,18h

简单到如此地步让我觉得相当诡异,只有几个赋值,乘,位移之类的操作怎么就把当前的时钟滴答数搞到手了呢?看了这篇文章以后大致知道内核中估计会定期更新0x7FFE0000这个地址上的内容,然后GetTickCount只需要获取这个地址上的值,再经过简单的计算就可以得出答案了。

Categories: programming Tags: , ,