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.

471 lines
12 KiB

  1. /*
  2. * servers.c
  3. *
  4. * Code that calls external servers such as symsrv.dll and srcsrv.dll
  5. */
  6. #include <private.h>
  7. #include <symbols.h>
  8. #include "globals.h"
  9. // forward reference
  10. void
  11. symsrvClose(
  12. VOID
  13. )
  14. {
  15. if (!g.hSymSrv)
  16. return;
  17. if (g.fnSymbolServerClose)
  18. g.fnSymbolServerClose();
  19. FreeLibrary(g.hSymSrv);
  20. g.hSymSrv = 0;
  21. g.fnSymbolServer = NULL;
  22. g.fnSymbolServerClose = NULL;
  23. g.fnSymbolServerSetOptions = NULL;
  24. }
  25. DWORD
  26. symsrvError(
  27. PPROCESS_ENTRY pe,
  28. BOOL success,
  29. LPCSTR params
  30. )
  31. {
  32. DWORD rc;
  33. char *sz;
  34. if (success)
  35. return NO_ERROR;
  36. rc = GetLastError();
  37. switch(rc)
  38. {
  39. case ERROR_PATH_NOT_FOUND:
  40. #if 0
  41. if (!g.fnSymbolServerPing)
  42. break;
  43. if (g.fnSymbolServerPing(params))
  44. break;
  45. symsrvClose();
  46. g.hSymSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  47. rc = GetLastError();
  48. evtprint(pe, sevProblem, ERROR_INVALID_NAME, NULL, "SYMSRV: %s is not available\n", params);
  49. break;
  50. #endif
  51. case ERROR_NOT_READY: // insert floppy
  52. case ERROR_FILE_NOT_FOUND: // obvious
  53. case ERROR_MORE_DATA: // didn't pass any tokens
  54. case ERROR_REQUEST_ABORTED: // user cancelled
  55. case 0: // hmmmmmmmmmmmm...
  56. break;
  57. case ERROR_INVALID_PARAMETER:
  58. symsrvClose();
  59. g.hSymSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  60. evtprint(pe, sevProblem, ERROR_INVALID_NAME, NULL, "SYMSRV: %s is not a valid store\n", params);
  61. break;
  62. case ERROR_INVALID_NAME:
  63. symsrvClose();
  64. g.hSymSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  65. evtprint(pe, sevProblem, ERROR_INVALID_NAME, NULL, "SYMSRV: %s needs a downstream store\n", params);
  66. break;
  67. case ERROR_FILE_INVALID:
  68. evtprint(pe, sevProblem, ERROR_FILE_INVALID, NULL, "SYMSRV: Compressed file needs a downstream store\n");
  69. break;
  70. default:
  71. break;
  72. }
  73. return rc;
  74. }
  75. BOOL
  76. symsrvPath(
  77. LPCSTR path
  78. )
  79. {
  80. if (!_strnicmp(path, "SYMSRV*", 7))
  81. return true;
  82. if (!_strnicmp(path, "SRV*", 4))
  83. return true;
  84. return false;
  85. }
  86. HMODULE
  87. LoadDLL(
  88. char *filename
  89. )
  90. /*
  91. * LoadLibrary() a DLL, but first try to do
  92. * it from the same directory as dbghelp.dll.
  93. */
  94. {
  95. char drive[10];
  96. char dir[MAX_PATH + 1];
  97. char file[MAX_PATH + 1];
  98. char ext[MAX_PATH + 1];
  99. char path[MAX_PATH + 1];
  100. HMODULE hm;
  101. _splitpath(filename, drive, dir, file, ext);
  102. if (!*drive && !*dir) {
  103. if (GetModuleFileName(g.hinst, path, MAX_PATH)) {
  104. _splitpath(path, drive, dir, NULL, NULL);
  105. if (*drive || *dir) {
  106. PrintString(path, DIMA(path), "%s%s%s%s", drive, dir, file, ext);
  107. hm = LoadLibrary(path);
  108. if (hm)
  109. return hm;
  110. }
  111. }
  112. }
  113. return LoadLibrary(filename);
  114. }
  115. DWORD
  116. symsrvGetFile(
  117. IN PPROCESS_ENTRY pe,
  118. IN LPCSTR ServerInfo,
  119. IN LPCSTR FileName,
  120. IN GUID *guid,
  121. IN DWORD two,
  122. IN DWORD three,
  123. OUT LPSTR FilePath
  124. )
  125. {
  126. BOOL rc;
  127. LPCSTR params;
  128. LPCSTR fname;
  129. char dll[MAX_PATH * 2];
  130. char proxy[MAX_PATH + 1];
  131. char path[MAX_PATH + 1];
  132. char drive[_MAX_DRIVE + 1];
  133. char dir[_MAX_DIR + 1];
  134. // strip any path information from the filename
  135. for (fname = FileName + strlen(FileName); fname > FileName; fname--) {
  136. if (*fname == '\\') {
  137. fname++;
  138. break;
  139. }
  140. }
  141. if (!ValidGuid(guid) && !two && !three) {
  142. pprint(pe, "Can't use symbol server for %s - no header information available\n", FileName);
  143. return ERROR_NO_DATA;
  144. }
  145. // initialize server, if needed
  146. if (g.hSymSrv == (HINSTANCE)INVALID_HANDLE_VALUE)
  147. return ERROR_MOD_NOT_FOUND;
  148. if (!_strnicmp(ServerInfo, "symsrv*", 7)) {
  149. params = strchr(ServerInfo + 7, '*');
  150. if (!params)
  151. return ERROR_INVALID_PARAMETER;
  152. if (!g.hSymSrv) {
  153. memcpy(dll, &ServerInfo[7], params - &ServerInfo[7]);
  154. dll[params - &ServerInfo[7]] = 0;
  155. if (!*dll)
  156. return ERROR_INVALID_PARAMETER;
  157. }
  158. params++;
  159. } else if (!_strnicmp(ServerInfo, "SRV*", 4)) {
  160. params = ServerInfo + 4;
  161. if (*params == 0 || *params == ';')
  162. params = "\\\\symbols\\symbols";
  163. else if (*params == '*')
  164. params = "*\\\\symbols\\symbols";
  165. if (!g.hSymSrv)
  166. CopyStrArray(dll, "symsrv.dll");
  167. }
  168. if (option(SYMOPT_SECURE))
  169. CopyStrArray(dll, "symsrv.dll");
  170. if (!g.hSymSrv) {
  171. g.hSymSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  172. g.hSymSrv = LoadDLL(dll);
  173. if (g.hSymSrv) {
  174. g.fnSymbolServer = (PSYMBOLSERVERPROC)GetProcAddress(g.hSymSrv, "SymbolServer");
  175. if (!g.fnSymbolServer) {
  176. FreeLibrary(g.hSymSrv);
  177. g.hSymSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  178. }
  179. g.fnSymbolServerClose = (PSYMBOLSERVERCLOSEPROC)GetProcAddress(g.hSymSrv, "SymbolServerClose");
  180. g.fnSymbolServerSetOptions = (PSYMBOLSERVERSETOPTIONSPROC)GetProcAddress(g.hSymSrv, "SymbolServerSetOptions");
  181. g.fnSymbolServerPing = (PSYMBOLSERVERPINGPROC)GetProcAddress(g.hSymSrv, "SymbolServerPing");
  182. symsrvSetOptions(SSRVOPT_PARAMTYPE, SSRVOPT_GUIDPTR);
  183. symsrvSetPrompts();
  184. symsrvSetCallback((option(SYMOPT_DEBUG) || g.hLog) ? true : false);
  185. if (GetEnvironmentVariable(SYMSRV_PROXY, proxy, DIMA(proxy)))
  186. symsrvSetOptions(SSRVOPT_PROXY, (ULONG_PTR)proxy);
  187. SymSetHomeDirectory(g.HomeDir);
  188. #if 0
  189. if (g.fnSymbolServerPing) {
  190. if (!g.fnSymbolServerPing(params)) {
  191. g.hSymSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  192. rc = GetLastError();
  193. evtprint(pe, sevProblem, ERROR_INVALID_NAME, NULL, "SYMSRV: %s is not available\n", params);
  194. }
  195. }
  196. #endif
  197. } else
  198. g.hSymSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  199. }
  200. // bail, if we have no valid server
  201. if (g.hSymSrv == INVALID_HANDLE_VALUE) {
  202. pprint(pe, "SymSrv load failure: %s\n", dll);
  203. return ERROR_MOD_NOT_FOUND;
  204. }
  205. SetCriticalErrorMode();
  206. #if 0
  207. if (g.fnSymbolServerPing)
  208. gfnSymbolServerPing(params);
  209. #endif
  210. if (option(SYMOPT_DEBUG)) {
  211. EnterCriticalSection(&g.threadlock);
  212. symsrvSetOptions(SSRVOPT_SETCONTEXT, (ULONG64)pe);
  213. }
  214. rc = g.fnSymbolServer(params, fname, guid, two, three, FilePath);
  215. if (option(SYMOPT_DEBUG)) {
  216. symsrvSetOptions(SSRVOPT_SETCONTEXT, NULL);
  217. LeaveCriticalSection(&g.threadlock);
  218. }
  219. rc = symsrvError(pe, rc, params);
  220. ResetCriticalErrorMode();
  221. return rc;
  222. }
  223. DWORD
  224. symsrvGetFileMultiIndex(
  225. IN PPROCESS_ENTRY pe,
  226. IN LPCSTR ServerInfo,
  227. IN LPCSTR FileName,
  228. IN DWORD index1,
  229. IN DWORD index2,
  230. IN DWORD two,
  231. IN DWORD three,
  232. OUT LPSTR FilePath
  233. )
  234. {
  235. GUID guid;
  236. DWORD err = ERROR_NO_DATA;
  237. ZeroMemory(&guid, sizeof(GUID));
  238. if (index1) {
  239. guid.Data1 = index1;
  240. err = symsrvGetFile(pe,
  241. ServerInfo,
  242. FileName,
  243. &guid,
  244. two,
  245. three,
  246. FilePath);
  247. if (err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND)
  248. return err;
  249. }
  250. if (index2 && (index2 != index1)) {
  251. guid.Data1 = index2;
  252. err = symsrvGetFile(pe,
  253. ServerInfo,
  254. FileName,
  255. &guid,
  256. two,
  257. three,
  258. FilePath);
  259. }
  260. return err;
  261. }
  262. BOOL
  263. symsrvCallback(
  264. UINT_PTR action,
  265. ULONG64 data,
  266. ULONG64 context
  267. )
  268. {
  269. PPROCESS_ENTRY pe = (PPROCESS_ENTRY)context;
  270. PIMAGEHLP_CBA_EVENT evt;
  271. BOOL rc = true;
  272. switch (action)
  273. {
  274. case SSRVACTION_TRACE:
  275. peprint(pe, (char *)data);
  276. break;
  277. case SSRVACTION_QUERYCANCEL:
  278. *(BOOL *)data = DoCallback(pe, CBA_DEFERRED_SYMBOL_LOAD_CANCEL, NULL);
  279. break;
  280. case SSRVACTION_EVENT:
  281. evt = (PIMAGEHLP_CBA_EVENT)data;
  282. peprint(pe, evt->desc);
  283. break;
  284. default:
  285. // unsupported
  286. rc = false;
  287. break;
  288. }
  289. return rc;
  290. }
  291. void
  292. symsrvSetOptions(
  293. ULONG_PTR options,
  294. ULONG64 data
  295. )
  296. {
  297. static ULONG_PTR ssopts = 0;
  298. static ULONG64 ssdata = 0;
  299. if (options != SSRVOPT_RESET) {
  300. ssopts = options;
  301. ssdata = data;
  302. }
  303. if (g.fnSymbolServerSetOptions)
  304. g.fnSymbolServerSetOptions(ssopts, ssdata);
  305. }
  306. void
  307. symsrvSetCallback(
  308. BOOL state
  309. )
  310. {
  311. if (state)
  312. symsrvSetOptions(SSRVOPT_CALLBACK, (ULONG64)symsrvCallback);
  313. else
  314. symsrvSetOptions(SSRVOPT_CALLBACK, 0);
  315. symsrvSetOptions(SSRVOPT_TRACE, state);
  316. }
  317. void symsrvSetPrompts()
  318. {
  319. symsrvSetOptions(SSRVOPT_PARENTWIN, (ULONG_PTR)g.hwndParent);
  320. if (option(SYMOPT_NO_PROMPTS))
  321. symsrvSetOptions(SSRVOPT_UNATTENDED, (ULONG_PTR)true);
  322. else
  323. symsrvSetOptions(SSRVOPT_UNATTENDED, (ULONG_PTR)false);
  324. }
  325. void symsrvSetDownstreamStore(
  326. char *dir
  327. )
  328. {
  329. symsrvSetOptions(SSRVOPT_DOWNSTREAM_STORE, (ULONG_PTR)dir);
  330. }
  331. BOOL
  332. srcsrvInit(
  333. HANDLE hp
  334. )
  335. {
  336. PPROCESS_ENTRY pe;
  337. if (g.hSrcSrv == (HINSTANCE)INVALID_HANDLE_VALUE)
  338. return false;
  339. pe = FindProcessEntry(hp);
  340. if (!g.hSrcSrv) {
  341. g.hSrcSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  342. g.hSrcSrv = LoadLibrary("srcsrv.dll");
  343. if (g.hSrcSrv) {
  344. g.fnSrcSrvInit = (PSRCSRVINITPROC)GetProcAddress(g.hSrcSrv, "SrcSrvInit");
  345. g.fnSrcSrvCleanup = (PSRCSRVCLEANUPPROC)GetProcAddress(g.hSrcSrv, "SrcSrvCleanup");
  346. g.fnSrcSrvSetTargetPath = (PSRCSRVSETTARGETPATHPROC)GetProcAddress(g.hSrcSrv, "SrcSrvSetTargetPath");
  347. g.fnSrcSrvSetOptions = (PSRCSRVSETOPTIONSPROC)GetProcAddress(g.hSrcSrv, "SrcSrvSetOptions");
  348. g.fnSrcSrvGetOptions = (PSRCSRVGETOPTIONSPROC)GetProcAddress(g.hSrcSrv, "SrcSrvGetOptions");
  349. g.fnSrcSrvLoadModule = (PSRCSRVLOADMODULEPROC)GetProcAddress(g.hSrcSrv, "SrcSrvLoadModule");
  350. g.fnSrcSrvUnloadModule = (PSRCSRVUNLOADMODULEPROC)GetProcAddress(g.hSrcSrv, "SrcSrvUnloadModule");
  351. g.fnSrcSrvRegisterCallback = (PSRCSRVREGISTERCALLBACKPROC)GetProcAddress(g.hSrcSrv, "SrcSrvRegisterCallback");
  352. g.fnSrcSrvGetFile = (PSRCSRVGETFILEPROC)GetProcAddress(g.hSrcSrv, "SrcSrvGetFile");
  353. if (!g.fnSrcSrvInit
  354. || !g.fnSrcSrvCleanup
  355. || !g.fnSrcSrvSetTargetPath
  356. || !g.fnSrcSrvSetOptions
  357. || !g.fnSrcSrvGetOptions
  358. || !g.fnSrcSrvLoadModule
  359. || !g.fnSrcSrvUnloadModule
  360. || !g.fnSrcSrvRegisterCallback
  361. || !g.fnSrcSrvGetFile)
  362. {
  363. FreeLibrary(g.hSrcSrv);
  364. g.hSrcSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  365. }
  366. gfnSrcSrvInit(hp, "c:\\src");
  367. gfnSrcSrvRegisterCallback(hp, srcsrvCallback, NULL);
  368. pprint(pe, "srcsrv loaded!\n");
  369. } else {
  370. g.hSrcSrv = (HINSTANCE)INVALID_HANDLE_VALUE;
  371. }
  372. }
  373. if (g.hSrcSrv != INVALID_HANDLE_VALUE)
  374. return true;
  375. return false;
  376. }
  377. BOOL
  378. srcsrvCallback(
  379. UINT_PTR action,
  380. DWORD64 data,
  381. DWORD64 context
  382. )
  383. {
  384. BOOL rc = true;
  385. char *sz;
  386. PPROCESS_ENTRY pe;;
  387. switch (action) {
  388. case SRCSRVACTION_TRACE:
  389. sz = (char *)data;
  390. pe = (PPROCESS_ENTRY)context;
  391. peprint(pe, (char *)data);
  392. break;
  393. default:
  394. // unsupported
  395. rc = false;
  396. break;
  397. }
  398. return rc;
  399. }