stdcall/cdecl/fastcall/thiscall/naked call

stdcall调用约定

stdcall很多时候被称为pascal调用约定,因为pascal是早期很常见的一种教学用计算机

程序设计语言,其语法严谨,使用的函数调用约定就是stdcall。在Microsoft C++系列

的C/C++编译器中,常常用PASCAL宏来声明这个调用约定,类似的宏还有WINAPI和CALLB

ACK。

 

stdcall调用约定声明的语法为(以前文的那个函数为例):

 

int __stdcall function(int a,int b)

 

stdcall的调用约定意味着:1)参数从右向左压入堆栈,2)函数自身修改堆栈 3)函数

名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸

 

以上述这个函数为例,参数b首先被压栈,然后是参数a,函数调用function(1,2)调用处

翻译成汇编语言将变成:

 

 

push 2 第二个参数入栈

push 1 第一个参数入栈

call function 调用参数,注意此时自动把cs:eip入栈

 

 

而对于函数自身,则可以翻译为:

 

 

push ebp 保存ebp寄存器,该寄存器将用来保存堆栈的栈顶指针,可以在函数退出

时恢复

mov ebp,esp 保存堆栈指针

mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向

a

add eax,[ebp + 0CH] 堆栈中ebp + 12处保存了b

mov esp,ebp 恢复esp

pop ebp

ret 8

 

而在编译时,这个函数的名字被翻译成_function@8

 

注意不同编译器会插入自己的汇编代码以提供编译的通用性,但是大体代码如此。其中

在函数开始处保留esp到ebp中,在函数结束恢复是编译器常用的方法。

 

从函数调用看,2和1依次被push进堆栈,而在函数中又通过相对于ebp(即刚进函数时的

堆栈指针)的偏移量存取参数。函数结束后,ret 8表示清理8个字节的堆栈,函数自己

恢复了堆栈。

 

cdecl调用约定

cdecl调用约定又称为C调用约定,是C语言缺省的调用约定,它的定义语法是:

 

 

int function (int a ,int b) //不加修饰就是C调用约定

int __cdecl function(int a,int b)//明确指出C调用约定

 

 

在写本文时,出乎我的意料,发现cdecl调用约定的参数压栈顺序是和stdcall是一样的

参数首先由右向左压入堆栈。所不同的是,函数本身不清理堆栈,调用者负责清理堆

。由于这种变化,C调用约定允许函数的参数的个数是不固定的,这也是C语言的一大

特色。对于前面的function函数,使用cdecl后的汇编码变成:

 

 

调用处

push 1

push 2

call function

add esp,8 注意:这里调用者在恢复堆栈

被调用函数_function处

push ebp 保存ebp寄存器,该寄存器将用来保存堆栈的栈顶指针,可以在函数退出

时恢复

mov ebp,esp 保存堆栈指针

mov eax,[ebp + 8H] 堆栈中ebp指向位置之前依次保存有ebp,cs:eip,a,b,ebp +8指向

a

add eax,[ebp + 0CH] 堆栈中ebp + 12处保存了b

mov esp,ebp 恢复esp

pop ebp

ret 注意,这里没有修改堆栈

 

 

MSDN中说,该修饰自动在函数名前加前导的下划线,因此函数名在符号表中被记录为_f

unction,但是我在编译时似乎没有看到这种变化。

 

由于参数按照从右向左顺序压栈,因此最开始的参数在最接近栈顶的位置,因此当采用

不定个数参数时,第一个参数在栈中的位置肯定能知道,只要不定的参数个数能够根据

第一个后者后续的明确的参数确定下来,就可以使用不定参数,例如对于CRT中的sprin

tf函数,定义为:

 

int sprintf(char* buffer,const char* format,...)

 

由于所有的不定参数都可以通过format确定,因此使用不定个数的参数是没有问题的。

 

fastcall

fastcall调用约定和stdcall类似,它意味着:

 

函数的第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过

从右向左的顺序压栈

被调用函数清理堆栈

函数名修改规则同stdcall

其声明语法为:int fastcall function(int a,int b)

 

thiscall

thiscall是唯一一个不能明确指明的函数修饰,因为thiscall不是关键字。它是C++类成

员函数缺省的调用约定。由于成员函数调用还有一个this指针,因此必须特殊处理,th

iscall意味着:

 

参数从右向左入栈

如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定,this指针

在所有参数压栈后被压入堆栈。

对参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈

为了说明这个调用约定,定义如下类和使用代码:

 

class A

{

public:

int function1(int a,int b);

int function2(int a,...);

};

int A::function1 (int a,int b)

{

return a+b;

}

#include

int A::function2(int a,...)

{

va_list ap;

va_start(ap,a);

int i;

int result = 0;

for(i = 0 i < a i ++)

{

result += va_arg(ap,int);

}

return result;

}

void callee()

{

A a;

a.function1 (1,2);

a.function2(3,1,2,3);

}

 

callee函数被翻译成汇编后就变成:

 

 

//函数function1调用

0401C1D push 2

00401C1F push 1

00401C21 lea ecx,[ebp-8]

00401C24 call function1 注意,这里this没有被入栈

//函数function2调用

00401C29 push 3

00401C2B push 2

00401C2D push 1

00401C2F push 3

00401C31 lea eax,[ebp-8] 这里引入this指针

00401C34 push eax

00401C35 call function2

00401C3A add esp,14h

 

可见,对于参数个数固定情况下,它类似于stdcall,不定时则类似cdecl

 

naked call

这是一个很少见的调用约定,一般程序设计者建议不要使用。编译器不会给这种函数增

加初始化和清理代码,更特殊的是,你不能用return返回返回值,只能用插入汇编返回

结果。这一般用于实模式驱动程序设计,假设定义一个求和的加法程序,可以定义为:

 

 

__declspec(naked) int add(int a,int b)

{

__asm mov eax,a

__asm add eax,b

__asm ret

}

 

注意,这个函数没有显式的return返回值,返回通过修改eax寄存器实现,而且连退出函

数的ret指令都必须显式插入。上面代码被翻译成汇编以后变成:

 

 

mov eax,[ebp+8]

add eax,[ebp+12]

ret 8

 

 

注意这个修饰是和__stdcall及cdecl结合使用的,前面是它和cdecl结合使用的代码,对

于和stdcall结合的代码,则变成:

 

__declspec(naked) int __stdcall function(int a,int b)

{

__asm mov eax,a

__asm add eax,b

__asm ret 8 //注意后面的8

}

 

至于这种函数被调用,则和普通的cdecl及stdcall调用函数一致。

 

函数调用约定导致的常见问题

如果定义的约定和使用的约定不一致,则将导致堆栈被破坏,导致严重问题,下面是两

种常见的问题:

 

函数原型声明和函数体定义不一致

DLL导入函数时声明了不同的函数约定

以后者为例,假设我们在dll种声明了一种函数为:

 

__declspec(dllexport) int func(int a,int b);//注意,这里没有stdcall,使用的是

cdecl

使用时代码为:

 

typedef int (*WINAPI DLLFUNC)func(int a,int b);

hLib = LoadLibrary(...);

DLLFUNC func = (DLLFUNC)GetProcAddress(...)//这里修改了调用约定

result = func(1,2);//导致错误

 

由于调用者没有理解WINAPI的含义错误的增加了这个修饰,上述代码必然导致堆栈被破

坏,MFC在编译时插入的checkesp函数将告诉你,堆栈被破坏了

 

posted @ 2009-04-13 17:03 Wang Wei 阅读(843) 评论(0) 编辑

wince5.0带的电源管理驱动只实现了“休眠(SUSPEND)”功能,未实现“关机(SHUT_DOWN)”功能。调用函数 SetSystemPowerState()时,无论参数是POWRE_STATE_OFF还是POWRE_STATE_SUSPEND,最终均为 SUSPEND。如果需要关机,还需要其他的办法。

我看过有人专门写了一个PowerKey的驱动,用来实现关机。但是这种方法的问题在于,关机时系统不会通知应用程序,往往需要自己设计一套消息由PowerKey驱动来通知应用程序,在很多时候非常的不方便。

我使用的方法是利用Wince自身的电源管理驱动,与系统结合的比较紧密

1. 建立新的PM PDD(platform.cpp),系统自带的PDD在WINCE500/PUBLIC/COMMON/OAK/DRIVERS/PM/PDD目录,可以选取一个作为修改的模板.同时,修改电源管理的SOURCE文件,使用新的PDD。

2.PlatformMapPowerStateHint()函数负责把电源状态标记映射为电源状态的名称,在此函数中做如下修改:

            把POWER_STATE_OFF映射为shutdown而不是suspend

3. PlatformSetSystemPowerState()函数负责设置电源的状态,函数中有这么一句

                     if((dwNewStateFlags & POWER_STATE_RESET) != 0)

     这一句监测是否用户准备RESET系统,并在后面做相应的RESET动作。

     在此之前,增加if((dwNewStateFlags & POWER_STATE_OFF) != 0){关机代码}

4. 在注册表文件中增加

; wwwwww, the following key is added to impliment the shut down function(not suspend)

; the application should deal with the POWER_BROADCAST(to POWER_STATE_OFF)

[HKEY_LOCAL_MACHINE"SYSTEM"CurrentControlSet"Control"Power"State"ShutDown]

    "Default"=dword:4           ; D4

    "Flags"=dword:20000         ; POWER_STATE_OFF

 5. 修改到此完成,关机时调用 SetSystemPowerState即可,StateFlags参数设为POWER_STATE_OFF。关机时,系统会向应用程序发送POWER_BROADCAST(to POWER_STATE_OFF)消息

 

posted @ 2008-12-08 12:03 Wang Wei 阅读(716) 评论(0) 编辑

最近在做一个项目,需要实现关机功能,可看来看去Wince只有Suspend,没有Shutdown.

无论是POWER_STATE_OFF还是POWER_STATE_SUSPEND最后实现的都是SUSPEND.

先提出问题了,先去Study一下,大家如果有答案的,也请告诉我。

posted @ 2008-11-24 11:34 Wang Wei 阅读(1020) 评论(0) 编辑

今天用到Locales ID,但怎么都找不到每种语言和地区对应的Locales ID,后来发现Locales ID的中文名是区域设置ID,这才Google到。现在把内容贴上来


语言 ID

语言 ID 决定网站中网页文本(例如“网站设置”页上的文本)使用的语言。创建网站时可用的语言取决于在服务器或服务器场中安装的语言模板包。基于 Windows SharePoint Services 的网站可用以下语言创建。

ID 语言 ID 语言
1025 阿拉伯语 1041 日语
1028 繁体中文 1042 朝鲜语
1029 捷克语 1043 荷兰语
1030 丹麦语 1044 挪威语
1031 德语 1045 波兰语
1032 希腊语 1046 葡萄牙语 - 巴西
1033 英语 1049 俄语
1034 西班牙语 1053 瑞典语
1035 芬兰语 1054 泰语
1036 法语 1055 土耳其语
1037 希伯来语 2052 简体中文
1038 匈牙利语 2070 葡萄牙语
1040 意大利语 3076 汉语 - 香港

Windows SharePoint Services 还支持用下列语言输入和显示文本,但不能用这些语言创建网站。

ID 语言 ID 语言
1026 保加利亚语 1048 罗马尼亚语
1050 克罗地亚语 2074 塞尔维亚语
1061 爱沙尼亚语 1051 斯洛伐克语
1081 印度印地语 1060 斯洛文尼亚语
1062 拉脱维亚语 1058 乌克兰语
1063 立陶宛语

区域设置 ID

区域设置 ID 控制网站的编号、排序、日历和时间格式。可以使用“区域设置”网页更改网站的区域设置。基于 Windows SharePoint Services 的网站可设置为以下区域设置 ID。

ID 区域设置 ID 区域设置
1078 南非荷兰语 1037 希伯来语
1052 阿尔巴尼亚语 1081 印地语
5121 阿拉伯语(阿尔及利亚) 1038 匈牙利语
15361 阿拉伯语(巴林) 1039 冰岛语
3073 阿拉伯语(埃及) 1057 印度尼西亚语
2049 阿拉伯语(伊拉克) 1040 意大利语(意大利)
11265 阿拉伯语(约旦) 2064 意大利语(瑞士)
13313 阿拉伯语(科威特) 1041 日语
12289 阿拉伯语(黎巴嫩) 1099 卡纳达语
4097 阿拉伯语(利比亚) 1087 哈萨克语
6145 阿拉伯语(摩洛哥) 1111 孔卡尼语
8193 阿拉伯语(阿曼) 1042 朝鲜语
16385 阿拉伯语(卡塔尔) 1088 吉尔吉斯语(西里尔文)
1025 阿拉伯语(沙特阿拉伯) 1062 拉脱维亚语
10241 阿拉伯语(叙利亚) 1063 立陶宛语
7169 阿拉伯语(突尼斯) 1071 马其顿语(FYROM)
14337 阿拉伯语(阿拉伯联合酋长国) 2110 马来语(文莱达鲁萨兰国)
9217 阿拉伯语(也门) 1086 马来语(马来西亚)
1067 亚美尼亚语 1102 马拉地语
2092 阿塞拜疆语(西里尔文) 1104 蒙古语(西里尔文)
1068 阿塞拜疆语(拉丁语系) 1044 挪威语(博克马尔语)
1069 巴斯克语 2068 挪威语(尼诺斯克语)
1059 白俄罗斯语 1045 波兰语
1026 保加利亚语 1046 葡萄牙语(巴西)
1027 加泰罗尼亚语 2070 葡萄牙语(葡萄牙)
3076 汉语(香港) 1094 旁遮普语
5124 汉语(澳门) 1048 罗马尼亚语
2052 汉语(中华人民共和国) 1049 俄语
4100 汉语(新加坡) 1103 梵语
1028 汉语(台湾) 3098 塞尔维亚语(西里尔文)
1050 克罗地亚语 2074 塞尔维亚语(拉丁语系)
1029 捷克语 1051 斯洛伐克语
1030 丹麦语 1060 斯洛文尼亚语
1125 马尔代夫语 11274 西班牙语(阿根廷)
2067 荷兰语(比利时) 16394 西班牙语(玻利维亚)
1043 荷兰语(荷兰) 13322 西班牙语(智利)
3081 英语(澳大利亚) 9226 西班牙语(哥伦比亚)
10249 英语(伯利兹) 5130 西班牙语(哥斯达黎加)
4105 英语(加拿大) 7178 西班牙语(多米尼加共和国)
9225 英语(加勒比海) 12298 西班牙语(厄瓜多尔)
6153 英语(爱尔兰) 17418 西班牙语(萨尔瓦多)
8201 英语(牙买加) 4106 西班牙语(危地马拉)
5129 英语(新西兰) 18442 西班牙语(洪都拉斯)
13321 英语(菲律宾) 2058 西班牙语(墨西哥)
7177 英语(南非) 19466 西班牙语(尼加拉瓜)
11273 英语(特立尼达岛) 6154 西班牙语(巴拿马)
2057 英语(英国) 15370 西班牙语(巴拉圭)
1033 英语(美国) 10250 西班牙语(秘鲁)
12297 英语(津巴布韦) 20490 西班牙语(波多黎各)
1061 爱沙尼亚语 3082 西班牙语(西班牙)
1080 法罗语 1034 西班牙语(传统风格)
1065 波斯语 14346 西班牙语(乌拉圭)
1035 芬兰语 8202 西班牙语(委内瑞拉)
2060 法语(比利时) 1089 斯瓦希里语
3084 法语(加拿大) 1053 瑞典语
1036 法语(法国) 2077 瑞典语(芬兰)
5132 法语(卢森堡) 1114 古叙利亚语
6156 法语(摩纳哥) 1097 泰米尔语
4108 法语(瑞士) 1092 鞑靼语
1110 加利西亚语 1098 泰卢固语
1079 格鲁吉亚语 1054 泰语
3079 德语(奥地利) 1055 土耳其语
1031 德语(德国) 1058 乌克兰语
5127 德语(列支敦士登) 1056 乌尔都语
4103 德语(卢森堡) 2115 乌兹别克语(西里尔文)
2055 德语(瑞士) 1091 乌兹别克语(拉丁语系)
1032 希腊语 1066 越南语
1095 古吉拉特语

时区

基于 Windows SharePoint Services 的网站可以设置为 Microsoft Windows Server 2003 承认的任何时区。

代码 时区 代码 时区
39 (GMT-12:00) 埃尼威托克,夸贾林岛 59 (GMT+02:00) 赫尔辛基,里加,塔林
16 (GMT-11:00) 中途岛, 萨摩亚群岛 27 (GMT+02:00) 耶路撒冷 26 (GMT+03:00) 巴格达
15 (GMT-10:00) 夏威夷 74 (GMT+03:00) 科威特,利雅得
14 (GMT-09:00) 阿拉斯加 51 (GMT+03:00) 莫斯科,圣彼得堡,伏尔加格勒
13 (GMT-08:00) 太平洋时间(美国和加拿大): 蒂华纳 56 (GMT+03:00) 内罗毕
38 (GMT-07:00) 亚利桑那 25 (GMT+03:30) 德黑兰
12 (GMT-07:00) 山区时间(美国和加拿大) 24 (GMT+04:00) 阿布扎比,马斯喀特
55 (GMT-06:00) 中美洲 54 (GMT+04:00) 巴库,第比利斯,埃里温 48 (GMT+04:30) 喀布尔
11 (GMT-06:00) 中部时间(美国和加拿大) 58 (GMT+05:00) 叶卡捷琳堡
37 (GMT-06:00) 墨西哥城 47 (GMT+05:00) 伊斯兰堡,卡拉奇,塔什干
36 (GMT-06:00) 萨斯喀彻温省 23 (GMT+05:30) 加尔各答,马德拉斯,孟买,新德里
35 (GMT-05:00) 波哥大,利马,基多 62 (GMT+05:45) 加德满都 46 (GMT+06:00) 阿拉木图,新西伯利亚
10 (GMT-05:00) 东部时间(美国和加拿大) 71 (GMT+06:00) 阿斯塔纳,达卡
34 (GMT-05:00) 印地安纳(东部) 66 (GMT+06:00) 科特
9 (GMT-04:00) 大西洋时间(加拿大) 61 (GMT+06:30) 仰光
33 (GMT-04:00) 加拉加斯,拉巴斯 22 (GMT+07:00) 曼谷,河内,雅加达
65 (GMT-04:00) 圣地亚哥 64 (GMT+07:00) 克拉斯诺亚尔斯克
28 (GMT-03:30) 纽芬兰 8 (GMT-03:00) 巴西利亚 45 (GMT+08:00) 北京,重庆,香港,乌鲁木齐
32 (GMT-03:00) 布宜诺斯艾利斯,乔治敦 63 (GMT+08:00) 伊尔库次克,乌兰巴托
60 (GMT-03:00) 格陵兰 21 (GMT+08:00) 吉隆坡,新加坡
30 (GMT-02:00) 中大西洋 73 (GMT+08:00) 珀斯 75 (GMT+08:00) 台北
29 (GMT-01:00) 亚速尔群岛 20 (GMT+09:00) 大坂,扎幌,东京 72 (GMT+09:00) 汉城
53 (GMT-01:00) 佛得角群岛 70 (GMT+09:00) 雅库茨克 19 (GMT+09:30) 阿德莱德
31 (GMT) 卡萨布兰卡,蒙罗维亚 44 (GMT+09:30) 达尔文
2 (GMT) 格林威治;都柏林,爱丁堡,里斯本,伦敦 18 (GMT+10:00) 布里斯班
4 (GMT+01:00) 阿姆斯特丹,柏林,伯尔尼,罗马,斯德哥尔摩,维也纳 76 (GMT+10:00) 堪培拉,墨尔本,悉尼
6 (GMT+01:00) 贝尔格莱德,布拉迪斯拉发,布达佩斯,卢布尔雅那,布拉格 43 (GMT+10:00) 关岛,莫尔兹比港
3 (GMT+01:00) 布鲁塞尔,哥本哈根,马德里,巴黎 42 (GMT+10:00) 霍巴特
57 (GMT+01:00) 萨拉热窝,斯科普里,索非亚,维尔纽斯,华沙,萨格勒布 68 (GMT+10:00) 符拉迪沃斯托克(海参崴)
69 (GMT+01:00) 中非西部 41 (GMT+11:00) 马加丹,所罗门群岛,新喀里多尼亚
7 (GMT+02:00) 雅典,伊斯坦布尔,明斯克 17 (GMT+12:00) 奥克兰,惠灵顿
5 (GMT+02:00) 布加勒斯特 40 (GMT+12:00) 斐济,勘察加半岛,马绍尔群岛
49 (GMT+02:00) 开罗 67 (GMT+13:00) 努库阿洛法
50 (GMT+02:00) 哈拉雷,比勒陀利亚

货币 ID

基于 Windows SharePoint Services 的网站可以设置为使用以下货币。

ID 货币 ID 货币
5121 1,254 .ج.د (阿拉伯地区-阿尔及利亚) 4106 Q1,254 (危地马拉)
15361 1,254 .ب.د (阿拉伯地区-巴林) 18442 L. 1254 (洪都拉斯)
3073 1,254 .م.ج (阿拉伯地区-埃及) 3076 HK$1,254 (香港)
2049 1,254 .ع.د (阿拉伯地区-伊拉克) 1038 1 254 Ft (匈牙利)
11265 1,254 .ا.د (阿拉伯地区-约旦) 1081 रु 1,254 (印度)
13313 1,254 .ك.د (阿拉伯地区-科威特) 6153 IR£1,254 (爱尔兰)
12289 1,254 .ل.ل (阿拉伯地区-黎巴嫩) 1037 ₪1,254 (以色列)
4097 1,254 .ل.د (阿拉伯地区-利比亚) 1041 ¥1,254 (日本)
6145 1,254 .م.د (阿拉伯地区-摩洛哥) 1042 ₩1,254 (韩国)
8193 1,254 .ع.ر (阿拉伯地区-阿曼) 2058 $1,254 (墨西哥)
16385 1,254 .ق.ر (阿拉伯地区-卡塔尔) 5129 $1,254 (新西兰)
1025 1,254 .س.ر (阿拉伯地区-沙特阿拉伯) 19466 C$ 1254 (尼加拉瓜)
10241 1,254 .س.ل (阿拉伯地区-叙利亚) 1044 kr 1 254 (挪威)
7169 1,254 .ت.د (阿拉伯地区-突尼斯) 1056 Rs 1,254 (巴基斯坦)
14337 1,254 .إ.د (阿拉伯地区-阿拉伯联合酋长国) 6154 B/. 1,254 (巴拿马)
9217 1,254 .ي.ر (阿拉伯地区-也门) 15370 Gs 1.254 (巴拉圭)
11274 $ 1.254 (阿根廷) 2052 ¥1,254 (中国)
3081 $1,254 (澳大利亚) 10250 S/. 1,254 (秘鲁)
3079 öS 1.254 (奥地利) 1045 1 254 zł (波兰)
16394 $b 1.254 (玻利维亚) 1049 1 254р. (俄罗斯)
1046 R$ 1.254 (巴西) 4100 $1,254 (新加坡)
3084 1 254 $ (加拿大) 1051 1 254 Sk (斯洛伐克)
4105 $1,254 (加拿大) 1060 1.254 SIT (斯洛文尼亚)
13322 $ 1.254 (智利) 7177 R 1,254 (南非)
9226 $ 1.254 (哥伦比亚) 1053 1.254 kr (瑞典)
5130 C1.254 (哥斯达黎加) 2055 SFr. 1'254 (瑞士)
1029 1 254 Kč (捷克共和国) 1028 NT$1,254 (台湾)
1030 kr 1.254 (丹麦) 1054 ฿1,254 (泰国)
7178 RD$1,254 (多米尼加共和国) 1055 1.254 TL (土耳其)
17418 C1254 (萨尔瓦多) 2057 £1,254 (英国)
-2 1,254 € (欧盟) 1033 $1,254 (美国)
-1 € 1,254 (欧盟) 14346 $U 1.254 (乌拉圭)
1065 1,254 ريال (波斯语) 8202 Bs 1.254 (委内瑞拉)
1032 1.254 Δρχ (希腊) 1066 1,254 ₫ (越南语)
posted @ 2008-08-15 11:24 Wang Wei 阅读(2121) 评论(1) 编辑

早晨上网发现,自己竟然上了微软中文技术论坛的解答排行榜。

虽然回答的都是些简单问题,而且只有两个问题被标记为有帮助的答案,但是还是把图抓下来,满足下自己的虚荣心。


posted @ 2008-08-08 10:43 Wang Wei 阅读(95) 评论(0) 编辑
posted @ 2008-07-31 18:21 Wang Wei 阅读(83) 评论(0) 编辑
posted @ 2008-07-10 10:12 Wang Wei 阅读(63) 评论(0) 编辑
posted @ 2008-07-01 09:27 Wang Wei 阅读(173) 评论(0) 编辑
posted @ 2008-06-30 10:12 Wang Wei 阅读(53) 评论(0) 编辑
posted @ 2008-06-30 10:08 Wang Wei 阅读(49) 评论(0) 编辑