Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

320 lines
8.6 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <string>
  4. #include <set>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <dbghelp.h>
  8. #define F_USE_USH_NAME 0x000001
  9. #define F_OUT_DIFF 0x000002
  10. #define F_OUT_USH 0x000004
  11. #define F_OUT_WCH 0x000008
  12. #define F_OUT_IDEN 0x000010
  13. #define F_OUT_DNAME 0x000020
  14. #define F_OUT_ALL 0x00001e
  15. using namespace std;
  16. int flags = 0;
  17. enum Ext { none, lib, dll};
  18. char tmp[512];
  19. Ext FindExt(const char *Fname)
  20. {
  21. Fname = strrchr(Fname, '.');
  22. if ( Fname == NULL)
  23. return none;
  24. else if ( !stricmp(Fname, ".Lib"))
  25. return lib;
  26. else if ( !stricmp(Fname, ".Dll"))
  27. return dll;
  28. else
  29. return none;
  30. }
  31. char *filter(char* ch, Ext fext)
  32. {
  33. char *str = strchr(ch, '?');
  34. return str == NULL ? ch: str;
  35. }
  36. const char* setflags(int argc, char *argv[])
  37. {
  38. const char *Fname = NULL;
  39. for (int i = 1; i < argc; i++)
  40. {
  41. if (argv[i][0] == '-' || argv[i][0] == '/')
  42. {
  43. for ( int j = 1; argv[i][j] != '\0'; j++)
  44. {
  45. switch (argv[i][j])
  46. {
  47. case 'u':
  48. case 'U':
  49. flags |= F_OUT_USH;
  50. break;
  51. case 'w':
  52. case 'W':
  53. flags |= F_OUT_WCH;
  54. break;
  55. case 'd':
  56. case 'D':
  57. flags |= F_OUT_DNAME;
  58. break;
  59. case 'i':
  60. case 'I':
  61. flags |= F_OUT_IDEN;
  62. break;
  63. case 'x':
  64. case 'X':
  65. flags |= F_USE_USH_NAME;
  66. break;
  67. default:
  68. return NULL;
  69. }
  70. }
  71. }
  72. else
  73. {
  74. if (!Fname)
  75. Fname = argv[i];
  76. else
  77. return NULL;
  78. }
  79. }
  80. if (!(flags & F_OUT_USH) && !(flags & F_OUT_WCH) && !(flags & F_OUT_IDEN))
  81. flags |= F_OUT_ALL;
  82. return Fname;
  83. }
  84. void print(string st)
  85. {
  86. if ( flags & F_OUT_DNAME)
  87. {
  88. if (UnDecorateSymbolName( st.c_str(), tmp, 511, 0))
  89. cout << tmp << '\n';
  90. else
  91. cout << st << '\n';
  92. } else {
  93. cout << st << '\n';
  94. }
  95. }
  96. int funccmp(const char *func1, const char *func2)
  97. {
  98. while (*func1 != 0 && *func2 != 0)
  99. {
  100. if ( *func1 == *func2)
  101. func1++, func2++;
  102. else if ( func1 == strstr(func1, "_W") &&
  103. func2 == strstr(func2, "G"))
  104. func1 += sizeof("_W"), func2 += sizeof("G");
  105. else if ( func2 == strstr(func2, "_W") &&
  106. func1 == strstr(func1, "G"))
  107. func2 += sizeof("_W"), func1 += sizeof("G");
  108. else
  109. break;
  110. }
  111. if (*func1 < *func2)
  112. return -1;
  113. else if (*func1 > *func2)
  114. return 1;
  115. else
  116. return 0;
  117. }
  118. int Funccmp(const char *func1, const char *func2)
  119. {
  120. static char tmp1[512];
  121. UnDecorateSymbolName(func1, tmp, 511, 0);
  122. UnDecorateSymbolName(func2, tmp1, 511, 0);
  123. func1 = tmp;
  124. func2 = tmp1;
  125. if (strstr(tmp, "wchar_t") || strstr(tmp, "unsigned short"))
  126. return 11;
  127. else if (strstr(tmp1, "wchar_t") || strstr(tmp1, "unsigned short"))
  128. return 22;
  129. while (*func1 != 0 && *func2 != 0)
  130. {
  131. if ( *func1 == *func2)
  132. func1++, func2++;
  133. else if ( func1 == strstr(func1, "wchar_t") &&
  134. func2 == strstr(func2, "unsigned short"))
  135. func1 += sizeof("wchar_t"), func2 += sizeof("unsigned short");
  136. else if ( func2 == strstr(func2, "wchar_t") &&
  137. func1 == strstr(func1, "unsigned short"))
  138. func2 += sizeof("wchar_t"), func1 += sizeof("unsigned short");
  139. else
  140. break;
  141. }
  142. if (*func1 < *func2)
  143. return -1;
  144. else if (*func1 > *func2)
  145. return 1;
  146. else
  147. return 0;
  148. }
  149. int main(int argc, char *argv[])
  150. {
  151. FILE *phDumpbin;
  152. Ext Fext;
  153. const char *Fname;
  154. int StripLine, i, result;
  155. char ExeName[256];
  156. char TmpStr[512];
  157. char *tch;
  158. set<string> Sdiff, Wdiff, Iden;
  159. if (!(Fname = setflags(argc, argv)))
  160. {
  161. cout << "Usage : wsfdiff -[options] filename" << endl;
  162. cout << "-x -X: Use unsigned char as data type in identical functions" << endl;
  163. cout << "-u -U: Print diff with unsigned short version" << endl;
  164. cout << "-w -W: Print diff with wchar_t version" << endl;
  165. cout << "-i -I: Print Identical function" << endl;
  166. cout << "-d -D: UnDname the function names" << endl;
  167. cout << "filename can only have be .lib or .dll" << endl;
  168. return -1;
  169. }
  170. strcpy(ExeName, "dumpbin ");
  171. switch (Fext = FindExt(Fname))
  172. {
  173. case dll:
  174. strcat(ExeName, "-exports ");
  175. break;
  176. case lib:
  177. strcat(ExeName, "-linkermember ");
  178. break;
  179. case none:
  180. return -1;
  181. }
  182. strcat(ExeName, Fname);
  183. phDumpbin = _popen(ExeName, "r");
  184. //Strip header
  185. if (Fext == dll)
  186. StripLine = 19;
  187. else
  188. StripLine = 18;
  189. for ( i = 0; i < StripLine; i++)
  190. {
  191. fgets(TmpStr, 511, phDumpbin);
  192. cerr << TmpStr;
  193. }
  194. set<string>::iterator spos, wpos;
  195. while (fgets(TmpStr, 511, phDumpbin))
  196. {
  197. tch = filter(TmpStr, Fext);
  198. tch[strlen(tch) -1] = '\0';
  199. UnDecorateSymbolName(tch, tmp, 511, 0);
  200. if (strstr (tmp, "wchar_t"))
  201. {
  202. spos = Sdiff.begin();
  203. result = -1;
  204. while(spos != Sdiff.end())
  205. {
  206. switch(result = funccmp(tch, (*spos).c_str()))
  207. {
  208. case 1:
  209. ++spos;
  210. break;
  211. case 0:
  212. if (flags & F_USE_USH_NAME)
  213. Iden.insert(*spos);
  214. else
  215. Iden.insert(string(tch));
  216. Sdiff.erase(spos);
  217. break;
  218. }
  219. if ( result != 1)
  220. {
  221. break;
  222. }
  223. }
  224. if (result != 0)
  225. Wdiff.insert(string(tch));
  226. } else if ( strstr(tmp, "unsigned short"))
  227. {
  228. spos = Wdiff.begin();
  229. result = -1;
  230. while(spos != Wdiff.end())
  231. {
  232. switch(result = funccmp(tch, (*spos).c_str()))
  233. {
  234. case 1:
  235. ++spos;
  236. break;
  237. case 0:
  238. if (flags & F_USE_USH_NAME)
  239. Iden.insert(string(tch));
  240. else
  241. Iden.insert(*spos);
  242. Wdiff.erase(spos);
  243. break;
  244. }
  245. if ( result != 1)
  246. break;
  247. }
  248. if (result != 0)
  249. Sdiff.insert(string(tch));
  250. }
  251. }
  252. // final checks for diffs and validity
  253. for ( wpos = Wdiff.begin(), spos = Sdiff.begin();
  254. spos != Sdiff.end() && wpos != Wdiff.end();)
  255. {
  256. switch(Funccmp((*wpos).c_str(), (*spos).c_str()))
  257. {
  258. case 0:
  259. if (flags & F_USE_USH_NAME)
  260. Iden.insert(*spos);
  261. else
  262. Iden.insert(*wpos);
  263. spos = Sdiff.erase(spos);
  264. wpos = Wdiff.erase(wpos);
  265. break;
  266. case 1:
  267. ++spos;
  268. break;
  269. case -1:
  270. ++wpos;
  271. break;
  272. case 11:
  273. wpos = Wdiff.erase(wpos);
  274. break;
  275. case 22:
  276. spos = Sdiff.erase(spos);
  277. }
  278. }
  279. if ( flags & F_OUT_USH)
  280. {
  281. cout << "Only Unsigned Short version " << Sdiff.size() << '\n';
  282. for_each (Sdiff.begin(), Sdiff.end(), print);
  283. cout <<"-----------------------------------------------------------\n";
  284. }
  285. if ( flags & F_OUT_WCH)
  286. {
  287. cout << "Only wchar_t versions " << Wdiff.size() << '\n';
  288. for_each (Wdiff.begin(), Wdiff.end(), print);
  289. cout <<"-----------------------------------------------------------\n";
  290. }
  291. if ( flags & F_OUT_IDEN)
  292. {
  293. cout <<"Both the versions are present " << Iden.size() << '\n';
  294. for_each (Iden.begin(), Iden.end(), print );
  295. cout <<"-----------------------------------------------------------\n";
  296. }
  297. return 1;
  298. }