Source code of Windows XP (NT5)
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.

312 lines
7.5 KiB

  1. #include <private.h>
  2. WCHAR **SymbolNames;
  3. typedef BOOL ( __cdecl *PPDBOPEN2W )(
  4. const wchar_t *,
  5. LNGNM_CONST char *,
  6. EC *,
  7. wchar_t *,
  8. size_t,
  9. PDB **
  10. );
  11. typedef BOOL ( __cdecl *PPDBCLOSE ) (
  12. PDB* ppdb
  13. );
  14. typedef BOOL (__cdecl *PPDBCOPYTOW2) (
  15. PDB *ppdb,
  16. const wchar_t *szTargetPdb,
  17. DWORD dwCopyFilter,
  18. PfnPDBCopyQueryCallback pfnCallBack,
  19. void * pvClientContext
  20. );
  21. PPDBOPEN2W pPDBOpen2W;
  22. PPDBCLOSE pPDBClose;
  23. PPDBCOPYTOW2 pPDBCopyToW2;
  24. wchar_t NewPdbName[_MAX_FNAME];
  25. CHAR SymbolName[2048];
  26. WCHAR SymbolNameW[2048];
  27. PWCHAR *SymbolsToRemove;
  28. ULONG SymbolCount;
  29. int
  30. __cdecl
  31. MyWcsCmp(const void*Ptr1, const void *Ptr2)
  32. {
  33. wchar_t*String1 = *(wchar_t**)Ptr1;
  34. wchar_t*String2 = *(wchar_t**)Ptr2;
  35. // printf("String1: %p - %ws\nString2: %p - %ws\n%d\n", String1, String1, String2, String2, wcscmp(String1, String2));
  36. return (wcscmp(String1, String2));
  37. }
  38. __cdecl
  39. MyWcsCmp2(const void*Ptr1, const void *Ptr2)
  40. {
  41. wchar_t*String1 = (wchar_t*)Ptr1;
  42. wchar_t*String2 = *(wchar_t**)Ptr2;
  43. // printf("String1: %p - %ws\nString2: %p - %ws\n%d\n", String1, String1, String2, String2, wcscmp(String1, String2));
  44. return (wcscmp(String1, String2));
  45. }
  46. BOOL
  47. LoadNamesFromSymbolFile(
  48. WCHAR *SymbolFileName
  49. )
  50. {
  51. FILE *SymbolFile;
  52. ULONG i;
  53. SymbolFile = _wfopen(SymbolFileName, L"rt");
  54. if (!SymbolFile)
  55. return FALSE;
  56. SymbolCount = 0;
  57. while (fgets(SymbolName,sizeof(SymbolName),SymbolFile)) {
  58. SymbolCount++;
  59. }
  60. fseek(SymbolFile, 0, SEEK_SET);
  61. SymbolsToRemove = (PWCHAR *) malloc(SymbolCount * sizeof(PWCHAR));
  62. if (!SymbolsToRemove) {
  63. fclose(SymbolFile);
  64. return FALSE;
  65. }
  66. SymbolCount = 0;
  67. while (fgets(SymbolName,sizeof(SymbolName),SymbolFile)) {
  68. // Remove trailing spaces
  69. if (strlen(SymbolName)) {
  70. PCHAR SymPtr = SymbolName + strlen(SymbolName) - 1;
  71. while ((*SymPtr == ' ') || (*SymPtr == '\r') || (*SymPtr == '\n')) {
  72. *SymPtr = '\0';
  73. SymPtr--;
  74. }
  75. }
  76. if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, SymbolName, -1, SymbolNameW, sizeof(SymbolName)) == 0) {
  77. fclose(SymbolFile);
  78. return FALSE;
  79. }
  80. SymbolsToRemove[SymbolCount] = malloc((wcslen(SymbolNameW) + 1) * sizeof(WCHAR));
  81. if (!SymbolsToRemove[SymbolCount]) {
  82. fclose(SymbolFile);
  83. return FALSE;
  84. }
  85. wcscpy(SymbolsToRemove[SymbolCount], SymbolNameW);
  86. SymbolCount++;
  87. }
  88. fclose(SymbolFile);
  89. qsort(&SymbolsToRemove[0], SymbolCount, sizeof(PWCHAR), MyWcsCmp);
  90. return TRUE;
  91. }
  92. BOOL PDBCALL PdbCopyFilterPublics (
  93. void * pvClientContext,
  94. DWORD dwFilterFlags,
  95. unsigned int offPublic,
  96. unsigned int sectPublic,
  97. unsigned int grfPublic,
  98. const wchar_t * szPublic,
  99. wchar_t ** pszNewPublic
  100. ) {
  101. static size_t cPubs = 0;
  102. static wchar_t wszNewName[2048];
  103. if (SymbolCount > 1) {
  104. if (bsearch(szPublic, &SymbolsToRemove[0], SymbolCount, sizeof(PWCHAR), MyWcsCmp2)) {
  105. return FALSE;
  106. }
  107. } else {
  108. if (!wcscmp(szPublic, *SymbolsToRemove)) {
  109. return FALSE;
  110. }
  111. }
  112. return TRUE;
  113. // if ((cPubs++ % 16) == 0) {
  114. // if ((cPubs % 32) == 1) {
  115. // wcscpy(wszNewName, szPublic);
  116. // wcscat(wszNewName, L"_BobsYerUncle");
  117. // *pszNewPublic = wszNewName;
  118. // }
  119. // return TRUE;
  120. // }
  121. // else {
  122. // return FALSE;
  123. // }
  124. }
  125. PDBCOPYCALLBACK PDBCALL PdbCopyQueryCallback(void * pv, PCC pccQuery) {
  126. switch (pccQuery) {
  127. case pccFilterPublics:
  128. return (PDBCOPYCALLBACK) PdbCopyFilterPublics;
  129. break;
  130. default:
  131. return NULL;
  132. }
  133. }
  134. void Usage(void)
  135. {
  136. _putws(L"Usage: removesym -d:<pdbdll path> -p:<pdbname> {-s:<symbol to remove> | -f:<file with symbols to remove>}");
  137. }
  138. int __cdecl wmain(int argc, wchar_t *argv[])
  139. {
  140. WCHAR *szPdbName = NULL;
  141. WCHAR *szNewPdbName = NULL;
  142. WCHAR *pSymbolName = NULL;
  143. WCHAR *pSymbolFileName = NULL;
  144. HINSTANCE hmodMsPdb;
  145. BOOL rc;
  146. LONG ErrorCode;
  147. WCHAR ErrorString[1024];
  148. PDB * pSrcPdb;
  149. int i;
  150. WCHAR PdbDllName[_MAX_PATH] = {0};
  151. WCHAR *pPdbDllPath = NULL;
  152. // Grab the arguments
  153. if (argc < 4) {
  154. Usage();
  155. return 1;
  156. }
  157. i = 1;
  158. while (i < argc)
  159. {
  160. if (argv[i][0] == L'-' || argv[i][0] == L'/') {
  161. if (argv[i][1] == L'p' && argv[i][2] == ':') {
  162. // Pdb Name
  163. szPdbName = &argv[i][3];
  164. } else
  165. if (argv[i][1] == L's' && argv[i][2] == ':') {
  166. // Single Symbol name
  167. pSymbolName = &argv[i][3];
  168. } else
  169. if (argv[i][1] == L'f' && argv[i][2] == ':') {
  170. // File with symbol names
  171. pSymbolFileName = &argv[i][3];
  172. } else
  173. if (argv[i][1] == L'd' && argv[i][2] == ':') {
  174. // Single Symbol name
  175. pPdbDllPath = &argv[i][3];
  176. } else {
  177. Usage();
  178. return 1;
  179. }
  180. }
  181. i++;
  182. }
  183. if (!szPdbName) {
  184. _putws(L"Pdb name missing");
  185. Usage();
  186. return 1;
  187. }
  188. if (!pSymbolName && !pSymbolFileName) {
  189. _putws(L"Symbol name or file missing");
  190. Usage();
  191. return 1;
  192. }
  193. if (pSymbolName && pSymbolFileName) {
  194. _putws(L"Symbol name and symbol file specified - only one allowed");
  195. Usage();
  196. return 1;
  197. }
  198. if (!pPdbDllPath) {
  199. _putws(L"Pdb DllPath not specified");
  200. Usage();
  201. return 1;
  202. }
  203. // If there's a symfile, load it
  204. if (pSymbolFileName) {
  205. rc = LoadNamesFromSymbolFile(pSymbolFileName);
  206. if (!rc) {
  207. _putws(L"Unable do load names from symbol file");
  208. exit(1);
  209. }
  210. } else {
  211. SymbolsToRemove = &pSymbolName;
  212. SymbolCount = 1;
  213. }
  214. // Load mspdb60.dll and the necessar api's
  215. wcscpy(PdbDllName, pPdbDllPath);
  216. wcscat(PdbDllName, L"\\mspdb60.dll");
  217. hmodMsPdb = LoadLibraryW(PdbDllName);
  218. if (!hmodMsPdb) {
  219. _putws(L"Unable to loadlib mspdb60.dll");
  220. exit(1);
  221. }
  222. pPDBOpen2W = (PPDBOPEN2W) GetProcAddress(hmodMsPdb, "PDBOpen2W");
  223. pPDBClose = (PPDBCLOSE) GetProcAddress(hmodMsPdb, "PDBClose");
  224. pPDBCopyToW2 = (PPDBCOPYTOW2) GetProcAddress(hmodMsPdb, "PDBCopyToW2");
  225. if (!pPDBOpen2W || !pPDBClose || !pPDBCopyToW2) {
  226. _putws(L"Unable to find the necessary api's in the pdb dll");
  227. FreeLibrary(hmodMsPdb);
  228. exit(1);
  229. }
  230. __try {
  231. rc = pPDBOpen2W(szPdbName, "r", &ErrorCode, ErrorString, sizeof(ErrorString) / sizeof(ErrorString[0]), &pSrcPdb);
  232. if (!rc) {
  233. _putws(L"Unable to open pdb for changes");
  234. leave;
  235. }
  236. szNewPdbName = _wtmpnam(NewPdbName);
  237. rc = pPDBCopyToW2(pSrcPdb, szNewPdbName, 1, PdbCopyQueryCallback, NULL);
  238. pPDBClose(pSrcPdb);
  239. if (!rc) {
  240. _putws(L"CopyTo operation failed");
  241. __leave;
  242. }
  243. rc = CopyFile(szNewPdbName, szPdbName, FALSE);
  244. if (!rc) {
  245. _putws(L"Unable to overwrite old pdb with new pdb");
  246. }
  247. DeleteFile(szNewPdbName);
  248. } __except (EXCEPTION_EXECUTE_HANDLER) {
  249. _putws(L"Exception occured in pdb api's");
  250. rc = FALSE;
  251. }
  252. FreeLibrary(hmodMsPdb);
  253. return(rc);
  254. }