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.

368 lines
8.6 KiB

  1. #include "pch.h"
  2. typedef enum {
  3. fncRead = 0,
  4. fncWrite,
  5. fncNone
  6. };
  7. int parseargs(int argc, char **argv, char *pdb, char *input, char *stream, DWORD size);
  8. int getcontent(char *filename, char **content);
  9. int ProcessPDB6(int argc, char **argv, char **env);
  10. #define fileexists(path) (GetFileAttributes(path) != 0xFFFFFFFF)
  11. extern "C" int __cdecl main(int argc, char **argv, char **env)
  12. {
  13. BOOL rc;
  14. int fnc = fncNone;
  15. char pdbname[MAX_PATH];
  16. char input[MAX_PATH];
  17. char streamname[MAX_PATH];
  18. PDB *pdb;
  19. EC ec;
  20. char errormsg[cbErrMax];
  21. Stream* pstream;
  22. char *buf = NULL;
  23. long size;
  24. long cb;
  25. bool success = false;
  26. fnc = parseargs(argc, argv, pdbname, input, streamname, MAX_PATH);
  27. if (fnc == fncNone)
  28. return success;
  29. *errormsg = 0;
  30. rc = PDBOpen(pdbname,
  31. (fnc == fncRead) ? "r" : "w",
  32. 0,
  33. &ec,
  34. errormsg,
  35. &pdb);
  36. if (!rc)
  37. {
  38. if (ec == ERROR_BAD_FORMAT)
  39. return ProcessPDB6(argc, argv, env);
  40. printf("error 0x%x opening %s\n", ec, pdbname);
  41. return success;
  42. }
  43. rc = PDBOpenStream(pdb, streamname, &pstream);
  44. if (!rc)
  45. {
  46. printf( "Could not open stream %s in %s.\n", streamname, pdbname);
  47. goto cleanup;
  48. }
  49. if (fnc == fncWrite)
  50. {
  51. size = getcontent(input, &buf);
  52. if (!size)
  53. goto cleanup;
  54. rc = StreamReplace(pstream, (void *)buf, (DWORD)size);
  55. if ( !rc )
  56. {
  57. printf( "StreamReplace failed for %s(%s).\n", pdbname, streamname);
  58. goto cleanup;
  59. }
  60. rc = PDBCommit( pdb );
  61. if ( !rc ) {
  62. printf( "PDBCommit failed for %s.\n", pdbname);
  63. goto cleanup;
  64. }
  65. success = true;
  66. }
  67. else if (fnc == fncRead)
  68. {
  69. size = StreamQueryCb(pstream);
  70. if (!size)
  71. goto cleanup;
  72. buf = (char *)calloc(size + 1, sizeof(char));
  73. if (!buf)
  74. goto cleanup;
  75. cb = size;
  76. rc = StreamRead(pstream, 0, buf, &cb);
  77. if (!rc)
  78. goto cleanup;
  79. if (cb != size)
  80. goto cleanup;
  81. printf(buf);
  82. success = true;
  83. }
  84. cleanup:
  85. if (buf)
  86. free(buf);
  87. if (pdb)
  88. rc = PDBClose(pdb);
  89. return success ? 0 : -1;
  90. }
  91. bool parsesz(char *sz, char *file, DWORD size)
  92. {
  93. if (*(sz + 2) != ':')
  94. return false;
  95. StringCchCopy(file, size, sz + 3);
  96. return (*file) ? true : false;
  97. return (GetFileAttributes(file) == 0xFFFFFFFF) ? false : true;
  98. }
  99. int parseerror()
  100. {
  101. printf("pdbstr -r/w -p:PdbFileName -i:StreamFileName -s:StreamName\n");
  102. return fncNone;
  103. }
  104. int parseargs(int argc, char **argv, char *pdb, char *input, char *stream, DWORD size)
  105. {
  106. // all input strings must be the same size
  107. int i;
  108. int rc;
  109. char *sz;
  110. rc = fncNone;
  111. assert(pdb && input && stream);
  112. *pdb = *input = *stream = 0;
  113. for (i = 0; i < argc; i++, argv++)
  114. {
  115. if (!i)
  116. continue;
  117. sz = *argv;
  118. if (*sz == '-' || *sz == '/')
  119. {
  120. switch(*(sz + 1))
  121. {
  122. case 'r':
  123. case 'R':
  124. rc = fncRead;
  125. break;
  126. case 'w':
  127. case 'W':
  128. rc = fncWrite;
  129. break;
  130. case 'p':
  131. case 'P':
  132. if (!parsesz(sz, pdb, size))
  133. return parseerror();
  134. break;
  135. case 'i':
  136. case 'I':
  137. if (!parsesz(sz, input, size))
  138. return parseerror();
  139. break;
  140. case 's':
  141. case 'S':
  142. if (!parsesz(sz, stream, size))
  143. return parseerror();
  144. break;
  145. default:
  146. return parseerror();
  147. }
  148. }
  149. }
  150. if (rc == fncNone)
  151. return parseerror();
  152. if (!fileexists(pdb))
  153. return parseerror();
  154. if (!*stream)
  155. return parseerror();
  156. if ((rc == fncWrite) && !fileexists(input))
  157. return parseerror();
  158. return rc;
  159. }
  160. int getcontent(char *filename, char **buf)
  161. {
  162. HANDLE hptr;
  163. DWORD size;
  164. DWORD cb;
  165. LPSTR p;
  166. bool success = false;
  167. hptr = CreateFile(filename,
  168. GENERIC_READ,
  169. FILE_SHARE_READ,
  170. NULL,
  171. OPEN_EXISTING,
  172. FILE_ATTRIBUTE_NORMAL,
  173. NULL);
  174. if (hptr == INVALID_HANDLE_VALUE)
  175. return 0;
  176. // test validity of file pointer
  177. size = GetFileSize(hptr, NULL);
  178. if (!size)
  179. goto cleanup;
  180. // allocate space for file
  181. *buf = (char *)calloc(size, sizeof(char));
  182. if (!*buf)
  183. goto cleanup;
  184. // read it in
  185. if (!ReadFile(hptr, *buf, size, &cb, 0))
  186. goto cleanup;
  187. if (cb != size)
  188. goto cleanup;
  189. success = true;
  190. cleanup:
  191. // done
  192. if (hptr)
  193. CloseHandle(hptr);
  194. if (!success)
  195. {
  196. if (*buf)
  197. free(*buf);
  198. return 0;
  199. }
  200. return size;
  201. }
  202. // all this stuff handles PDB6 format
  203. typedef BOOL (PDBCALL *PfnPDBOpenStream)(PDB* ppdb, const char* szStream, OUT Stream** ppstream);
  204. typedef BOOL (PDBCALL *PfnStreamReplace)(Stream* pstream, void* pvBuf, long cbBuf);
  205. typedef BOOL (PDBCALL *PfnPDBCommit)(PDB* ppdb);
  206. typedef BOOL (PDBCALL *PfnPDBClose)(PDB* ppdb);
  207. PfnPDBOpen fnPDBOpen = NULL;
  208. PfnPDBOpenStream fnPDBOpenStream = NULL;
  209. PfnStreamReplace fnStreamReplace = NULL;
  210. PfnPDBCommit fnPDBCommit = NULL;
  211. PfnPDBClose fnPDBClose = NULL;
  212. int ProcessPDB6(int argc, char **argv, char **env)
  213. {
  214. BOOL rc;
  215. int fnc = fncNone;
  216. char pdbname[MAX_PATH];
  217. char input[MAX_PATH];
  218. char streamname[MAX_PATH];
  219. PDB *pdb;
  220. EC ec;
  221. char errormsg[cbErrMax];
  222. Stream* pstream;
  223. char *buf = NULL;
  224. long size;
  225. long cb;
  226. bool success = false;
  227. HINSTANCE hmspdb;
  228. fnc = parseargs(argc, argv, pdbname, input, streamname, MAX_PATH);
  229. if (fnc == fncNone)
  230. return success;
  231. hmspdb = LoadLibrary("mspdb60.dll");
  232. if (!hmspdb)
  233. {
  234. printf("error 0x%x loading mspdb60.dll\n", GetLastError());
  235. return success;
  236. }
  237. fnPDBOpen = (PfnPDBOpen)GetProcAddress(hmspdb, "PDBOpen");
  238. fnPDBOpenStream = (PfnPDBOpenStream)GetProcAddress(hmspdb, "PDBOpenStream");
  239. fnStreamReplace = (PfnStreamReplace)GetProcAddress(hmspdb, "StreamReplace");
  240. fnPDBCommit = (PfnPDBCommit)GetProcAddress(hmspdb, "PDBCommit");
  241. fnPDBClose = (PfnPDBClose)GetProcAddress(hmspdb, "PDBClose");
  242. if (!fnPDBOpen || !fnPDBOpenStream || !fnStreamReplace || !fnPDBCommit || !fnPDBClose)
  243. {
  244. printf("error 0x%x searching for exports in mspdb60.dll\n", GetLastError());
  245. return success;
  246. }
  247. *errormsg = 0;
  248. rc = fnPDBOpen(pdbname,
  249. (fnc == fncRead) ? "r" : "w",
  250. 0,
  251. &ec,
  252. errormsg,
  253. &pdb);
  254. if (!rc)
  255. {
  256. printf("error 0x%x opening %s\n", ec, pdbname);
  257. return success;
  258. }
  259. rc = fnPDBOpenStream(pdb, streamname, &pstream);
  260. if (!rc)
  261. {
  262. printf( "Could not open stream %s in %s.\n", streamname, pdbname);
  263. goto cleanup;
  264. }
  265. if (fnc == fncWrite)
  266. {
  267. size = getcontent(input, &buf);
  268. if (!size)
  269. goto cleanup;
  270. rc = fnStreamReplace(pstream, (void *)buf, (DWORD)size);
  271. if ( !rc )
  272. {
  273. printf( "StreamReplace failed for %s(%s).\n", pdbname, streamname);
  274. goto cleanup;
  275. }
  276. rc = fnPDBCommit( pdb );
  277. if ( !rc ) {
  278. printf( "PDBCommit failed for %s.\n", pdbname);
  279. goto cleanup;
  280. }
  281. success = true;
  282. }
  283. else if (fnc == fncRead)
  284. {
  285. size = StreamQueryCb(pstream);
  286. if (!size)
  287. goto cleanup;
  288. buf = (char *)calloc(size + 1, sizeof(char));
  289. if (!buf)
  290. goto cleanup;
  291. cb = size;
  292. rc = StreamRead(pstream, 0, buf, &cb);
  293. if (!rc)
  294. goto cleanup;
  295. if (cb != size)
  296. goto cleanup;
  297. printf(buf);
  298. success = true;
  299. }
  300. cleanup:
  301. if (buf)
  302. free(buf);
  303. if (pdb)
  304. rc = fnPDBClose(pdb);
  305. return success ? 0 : -1;
  306. }