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.

747 lines
21 KiB

  1. /******************************************************************************
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. faulth.c
  5. Abstract:
  6. Implements fault reporting functions
  7. Revision History:
  8. Much of this code taken from admin\pchealth\client\faultrep
  9. ******************************************************************************/
  10. #include <windows.h>
  11. #include <winver.h>
  12. #include <ntverp.h>
  13. #include <errorrep.h>
  14. #include "util.h"
  15. #include "faulth.h"
  16. //#define TEST_WATSON 1
  17. static LPWSTR
  18. plstrcpynW(
  19. LPWSTR lpString1,
  20. LPCWSTR lpString2,
  21. int iMaxLength
  22. )
  23. {
  24. LPWSTR src,dst;
  25. __try {
  26. src = (LPWSTR)lpString2;
  27. dst = lpString1;
  28. if ( iMaxLength ) {
  29. while(iMaxLength && *src){
  30. *dst++ = *src++;
  31. iMaxLength--;
  32. }
  33. if ( iMaxLength ) {
  34. *dst = '\0';
  35. }
  36. else {
  37. dst--;
  38. *dst = '\0';
  39. }
  40. }
  41. }
  42. __except (EXCEPTION_EXECUTE_HANDLER) {
  43. return NULL;
  44. }
  45. return lpString1;
  46. }
  47. #define sizeofSTRW(wsz) sizeof(wsz) / sizeof(wsz[0])
  48. ///////////////////////////////////////////////////////////////////////////////
  49. // Global stuff
  50. #ifdef TEST_WATSON
  51. const CHAR c_szDWDefServerI[] = "officewatson";
  52. #else
  53. const CHAR c_szDWDefServerI[] = "watson.microsoft.com";
  54. #endif
  55. const CHAR c_szDWBrand[] = "WINDOWS";
  56. const WCHAR c_wzDWDefAppName[] = L"Application";
  57. const CHAR c_wszDWCmdLineU[] = "%s\\dwwin.exe -x -s %lu";
  58. #define c_DWDefaultLCID 1033
  59. _inline DWORD RolloverSubtract(DWORD dwA, DWORD dwB)
  60. {
  61. return (dwA >= dwB) ? (dwA - dwB) : (dwA + ((DWORD)-1 - dwB));
  62. }
  63. DWORD
  64. MyGetModuleFileNameA(
  65. IN HMODULE Module,
  66. OUT PSTR Buffer,
  67. IN DWORD BufferLength
  68. )
  69. {
  70. DWORD d = GetModuleFileNameA(Module, Buffer, BufferLength);
  71. Buffer[BufferLength - 1] = 0;
  72. return d < BufferLength ? d : 0;
  73. }
  74. #ifdef TEST_WATSON
  75. HANDLE hFaultLog = INVALID_HANDLE_VALUE;
  76. char *c_wszLogFileName = "faulth.log";
  77. // Need to synchroize this?
  78. static DebugLog(char *pszMessage, ...)
  79. {
  80. va_list arglist;
  81. if( !pszMessage)
  82. return 0;
  83. va_start(arglist,pszMessage);
  84. if (hFaultLog != INVALID_HANDLE_VALUE)
  85. {
  86. SYSTEMTIME st;
  87. DWORD cb, cbWritten;
  88. char szMsg[512];
  89. GetSystemTime(&st);
  90. cb = wsprintf(szMsg,
  91. "%02d-%02d-%04d %02d:%02d:%02d ",
  92. st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond
  93. );
  94. WriteFile(hFaultLog, szMsg, cb, &cbWritten, NULL);
  95. /*cb = FormatMessageA(
  96. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  97. pszMessage,
  98. 0,0,
  99. szMsg,
  100. 0,
  101. &arglist
  102. );*/
  103. cb = wsprintf(szMsg, pszMessage, &arglist);
  104. WriteFile(hFaultLog, szMsg, cb, &cbWritten, NULL);
  105. }
  106. va_end(arglist);
  107. return 1;
  108. }
  109. #else
  110. #define DebugLog(x)
  111. #endif
  112. HINSTANCE g_hInstance = NULL;
  113. ///////////////////////////////////////////////////////////////////////////////
  114. // DllMain
  115. // **************************************************************************
  116. BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  117. {
  118. switch(dwReason)
  119. {
  120. case DLL_PROCESS_ATTACH:
  121. g_hInstance = hInstance;
  122. //DisableThreadLibraryCalls(hInstance);
  123. break;
  124. case DLL_PROCESS_DETACH:
  125. break;
  126. }
  127. return TRUE;
  128. }
  129. static
  130. EFaultRepRetVal
  131. StartDWException(
  132. IN PSETUP_FAULT_HANDLER This,
  133. IN LPEXCEPTION_POINTERS pep,
  134. IN DWORD dwOpt,
  135. IN DWORD dwFlags,
  136. IN DWORD dwTimeToWait)
  137. {
  138. SECURITY_ATTRIBUTES sa;
  139. PROCESS_INFORMATION pi;
  140. EFaultRepRetVal frrvRet = frrvErrNoDW;
  141. DWSharedMem15 *pdwsm = NULL;
  142. STARTUPINFOA si;
  143. HRESULT hr = NOERROR;
  144. HANDLE hevDone = NULL, hevAlive = NULL, hmut = NULL;
  145. HANDLE hfmShared = NULL, hProc = NULL;
  146. HANDLE rghWait[2];
  147. DWORD dw, dwStart;
  148. BOOL fDWRunning = TRUE;
  149. char szCmdLine[MAX_PATH], szDir[MAX_PATH];
  150. char szModuleFileName[DW_MAX_PATH];
  151. char *pch;
  152. VALIDATEPARM(hr, (pep == NULL));
  153. if (FAILED(hr))
  154. goto done;
  155. // we need the following things to be inheritable, so create a SD that
  156. // says it can be.
  157. ZeroMemory(&sa, sizeof(sa));
  158. sa.nLength = sizeof(sa);
  159. sa.bInheritHandle = TRUE;
  160. // create the necessary events & mutexes
  161. hevDone = CreateEvent(&sa, FALSE, FALSE, NULL);
  162. TESTBOOL(hr, (hevDone != NULL));
  163. if (FAILED(hr))
  164. goto done;
  165. hevAlive = CreateEvent(&sa, FALSE, FALSE, NULL);
  166. TESTBOOL(hr, (hevAlive != NULL));
  167. if (FAILED(hr))
  168. goto done;
  169. hmut = CreateMutex(&sa, FALSE, NULL);
  170. TESTBOOL(hr, (hmut != NULL));
  171. if (FAILED(hr))
  172. goto done;
  173. TESTBOOL(hr, DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
  174. GetCurrentProcess(), &hProc,
  175. PROCESS_ALL_ACCESS, TRUE, 0));
  176. if (FAILED(hr))
  177. goto done;
  178. // create the shared memory region & map it
  179. hfmShared = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0,
  180. sizeof(DWSharedMem), NULL);
  181. TESTBOOL(hr, (hfmShared != NULL));
  182. if (FAILED(hr))
  183. goto done;
  184. pdwsm = (DWSharedMem *)MapViewOfFile(hfmShared,
  185. FILE_MAP_READ | FILE_MAP_WRITE, 0, 0,
  186. 0);
  187. TESTBOOL(hr, (pdwsm != NULL));
  188. if (FAILED(hr))
  189. goto done;
  190. // populate all the stuff that DW needs
  191. ZeroMemory(pdwsm, sizeof(DWSharedMem15));
  192. pdwsm->dwSize = sizeof(DWSharedMem15);
  193. pdwsm->pid = GetCurrentProcessId();
  194. pdwsm->tid = GetCurrentThreadId();
  195. pdwsm->eip = (DWORD_PTR)pep->ExceptionRecord->ExceptionAddress;
  196. pdwsm->pep = pep;
  197. pdwsm->hEventDone = hevDone;
  198. pdwsm->hEventNotifyDone = NULL;
  199. pdwsm->hEventAlive = hevAlive;
  200. pdwsm->hMutex = hmut;
  201. pdwsm->hProc = hProc;
  202. pdwsm->bfDWBehaviorFlags = dwFlags;
  203. pdwsm->msoctdsResult = msoctdsNull;
  204. pdwsm->fReportProblem = FALSE;
  205. pdwsm->bfmsoctdsOffer = msoctdsQuit;
  206. pdwsm->bfmsoctdsNotify = 0;
  207. if (dwOpt == 1)
  208. pdwsm->bfmsoctdsOffer |= msoctdsDebug;
  209. pdwsm->bfmsoctdsLetRun = pdwsm->bfmsoctdsOffer;
  210. pdwsm->iPingCurrent = 0;
  211. pdwsm->iPingEnd = 0;
  212. pdwsm->lcidUI = 1033;
  213. lstrcpynA( pdwsm->szServer, This->szURL, DW_MAX_SERVERNAME);
  214. lstrcpynA( pdwsm->szBrand, c_szDWBrand, DW_APPNAME_LENGTH);
  215. MyGetModuleFileNameA( NULL, szModuleFileName, DW_MAX_PATH);
  216. MultiByteToWideChar( CP_ACP, 0, szModuleFileName, -1, pdwsm->wzModuleFileName, DW_MAX_PATH);
  217. plstrcpynW( pdwsm->wzFormalAppName, This->wzAppName, DW_APPNAME_LENGTH);
  218. plstrcpynW( pdwsm->wzAdditionalFile, This->wzAdditionalFiles, DW_MAX_ADDFILES);
  219. plstrcpynW( pdwsm->wzErrorText, This->wzErrorText, DW_MAX_ERROR_CWC);
  220. // create the process
  221. if (!MyGetModuleFileNameA( g_hInstance, szDir, MAX_PATH) ||
  222. !(pch = strrchr (szDir, '\\'))) {
  223. goto done;
  224. }
  225. *pch = '\0';
  226. wsprintf( szCmdLine, c_wszDWCmdLineU, szDir, hfmShared);
  227. DebugLog( "CommandLine ");
  228. DebugLog( szCmdLine);
  229. DebugLog( "CurrentDir ");
  230. DebugLog( szDir);
  231. ZeroMemory(&si, sizeof(si));
  232. ZeroMemory(&pi, sizeof(pi));
  233. si.cb = sizeof(si);
  234. si.lpDesktop = "Winsta0\\Default";
  235. TESTBOOL(hr, CreateProcessA(NULL, szCmdLine, NULL, NULL, TRUE,
  236. CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS,
  237. NULL, szDir, &si, &pi));
  238. if (FAILED(hr))
  239. goto done;
  240. // don't need the thread handle & we gotta close it, so close it now
  241. CloseHandle(pi.hThread);
  242. // assume we succeed from here on...
  243. frrvRet = frrvOk;
  244. rghWait[0] = hevAlive;
  245. rghWait[1] = pi.hProcess;
  246. dwStart = GetTickCount();
  247. while(fDWRunning)
  248. {
  249. // gotta periodically get the Alive signal from DW.
  250. switch(WaitForMultipleObjects(2, rghWait, FALSE, 120000))
  251. {
  252. case WAIT_OBJECT_0:
  253. if (WaitForSingleObject(hevDone, 0) == WAIT_OBJECT_0)
  254. fDWRunning = FALSE;
  255. if (dwTimeToWait != (DWORD)-1 &&
  256. RolloverSubtract(GetTickCount(), dwStart) > dwTimeToWait)
  257. {
  258. frrvRet = frrvErrTimeout;
  259. fDWRunning = FALSE;
  260. }
  261. continue;
  262. case WAIT_OBJECT_0 + 1:
  263. fDWRunning = FALSE;
  264. continue;
  265. }
  266. switch(WaitForSingleObject(hmut, DW_TIMEOUT_VALUE))
  267. {
  268. // yay! we got the mutex. Try to detemine if DW finally responded
  269. // while we were grabbing the mutex.
  270. case WAIT_OBJECT_0:
  271. switch(WaitForMultipleObjects(2, rghWait, FALSE, 0))
  272. {
  273. // If it hasn't responded, tell it to go away & fall thru
  274. // into the 'it died' case.
  275. case WAIT_TIMEOUT:
  276. SetEvent(hevDone);
  277. // It died. Clean up.
  278. case WAIT_OBJECT_0 + 1:
  279. fDWRunning = FALSE;
  280. frrvRet = frrvErrNoDW;
  281. continue;
  282. }
  283. // ok, it responded. Is it done?
  284. if (WaitForSingleObject(hevDone, 0) == WAIT_OBJECT_0)
  285. fDWRunning = FALSE;
  286. ReleaseMutex(hmut);
  287. break;
  288. // if the wait was abandoned, it means DW has gone to the great bit
  289. // bucket in the sky without cleaning up. So release the mutex and
  290. // fall into the default case
  291. case WAIT_ABANDONED:
  292. ReleaseMutex(hmut);
  293. // if we timed out or otherwise failed, just die.
  294. default:
  295. frrvRet = frrvErrNoDW;
  296. fDWRunning = FALSE;
  297. break;
  298. }
  299. }
  300. if (frrvRet != frrvOk)
  301. {
  302. CloseHandle(pi.hProcess);
  303. goto done;
  304. }
  305. // if user told us to debug, return that back to the
  306. if (pdwsm->msoctdsResult == msoctdsDebug)
  307. frrvRet = frrvLaunchDebugger;
  308. // if we're going to launch Dr. Watson, wait for the DW process to die.
  309. // Give it 5 minutes. If the user doesn't hit close by then, just return
  310. // anyway...
  311. if (dwOpt == (DWORD)-1)
  312. {
  313. if (WaitForSingleObject(pi.hProcess, 300000) == WAIT_TIMEOUT)
  314. frrvRet = frrvErrTimeout;
  315. }
  316. CloseHandle(pi.hProcess);
  317. done:
  318. // preserve the error code so that the following calls don't overwrite it
  319. dw = GetLastError();
  320. if (pdwsm != NULL)
  321. UnmapViewOfFile(pdwsm);
  322. if (hfmShared != NULL)
  323. CloseHandle(hfmShared);
  324. if (hevDone != NULL)
  325. CloseHandle(hevDone);
  326. if (hevAlive != NULL)
  327. CloseHandle(hevAlive);
  328. if (hmut != NULL)
  329. CloseHandle(hmut);
  330. if (hProc != NULL)
  331. CloseHandle(hProc);
  332. SetLastError(dw);
  333. return frrvRet;
  334. }
  335. static
  336. EFaultRepRetVal
  337. FaultHandler(
  338. IN PSETUP_FAULT_HANDLER This,
  339. IN EXCEPTION_POINTERS *pep,
  340. IN DWORD dwOpt)
  341. {
  342. EFaultRepRetVal frrvRet = frrvErrNoDW;
  343. DWORD dwFlags = 0;
  344. char wszFile[MAX_PATH], *pwsz;
  345. DebugLog("Inside FaultHandler\r\n");
  346. MyGetModuleFileNameA(NULL, wszFile, sizeof(wszFile)/sizeof(wszFile[0]));
  347. // Find last backslash
  348. for(pwsz = wszFile + strlen(wszFile);
  349. pwsz >= wszFile && *pwsz != '\\';
  350. pwsz--);
  351. // Should never happen
  352. if (pwsz < wszFile)
  353. goto done;
  354. if (*pwsz == '\\')
  355. pwsz++;
  356. // Don't want to debug dwwin.exe itself.
  357. if (_stricmp(pwsz, "dwwin.exe") == 0
  358. // || _stricmp(pwsz, "dumprep.exe") == 0
  359. )
  360. goto done;
  361. frrvRet = StartDWException(This, pep, dwOpt, dwFlags, -1);
  362. done:
  363. return frrvRet;
  364. }
  365. static
  366. BOOL
  367. FAULTHIsSupported(
  368. IN PSETUP_FAULT_HANDLER This
  369. )
  370. {
  371. BOOL useExtendedInfo;
  372. DWORD dwServicePack;
  373. DWORD dwVersion,dwTemp,dwInfoSize;
  374. char *pInfo;
  375. VS_FIXEDFILEINFO *VsInfo;
  376. UINT DataLength;
  377. union {
  378. OSVERSIONINFO Normal;
  379. OSVERSIONINFOEX Ex;
  380. } Ovi;
  381. DebugLog("Inside FAULTHIsSupported\r\n");
  382. if ( !This) {
  383. return(FALSE);
  384. }
  385. useExtendedInfo = TRUE;
  386. Ovi.Ex.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  387. if (!GetVersionEx((OSVERSIONINFO *)&Ovi.Ex) ) {
  388. //
  389. // EX size not available; try the normal one
  390. //
  391. Ovi.Normal.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  392. if (!GetVersionEx((OSVERSIONINFO *)&Ovi.Normal) ) {
  393. DebugLog("Inside FAULTHIsSupported:Could not get os version!\r\n");
  394. return(FALSE);
  395. }
  396. useExtendedInfo = FALSE;
  397. }
  398. if (useExtendedInfo) {
  399. dwServicePack = Ovi.Ex.wServicePackMajor * 100 + Ovi.Ex.wServicePackMinor;
  400. } else {
  401. dwServicePack = 0;
  402. }
  403. dwVersion = Ovi.Normal.dwMajorVersion * 100 + Ovi.Normal.dwMinorVersion;
  404. switch (Ovi.Normal.dwPlatformId) {
  405. case VER_PLATFORM_WIN32s:
  406. DebugLog("Inside FAULTHIsSupported:Unsupported win32s!\r\n");
  407. return(FALSE);
  408. break;
  409. case VER_PLATFORM_WIN32_WINDOWS:
  410. if( dwVersion < 410) {
  411. DebugLog("Inside FAULTHIsSupported:Unsupported win9x!\r\n");
  412. return(FALSE);
  413. }
  414. break;
  415. case VER_PLATFORM_WIN32_NT:
  416. if( dwVersion < 400) {
  417. DebugLog("Inside FAULTHIsSupported:Unsupported winNT!\r\n");
  418. return(FALSE);
  419. }
  420. if( dwVersion == 400 && dwServicePack < 500) {
  421. DebugLog("Inside FAULTHIsSupported:Unsupported ServicePack!\r\n");
  422. return(FALSE);
  423. }
  424. break;
  425. default:
  426. return(FALSE);
  427. }
  428. // Test for wininet.dll from ie 4.01.
  429. dwInfoSize = GetFileVersionInfoSize( FAULTH_WININET_NAME, &dwTemp );
  430. if( !dwInfoSize) {
  431. DebugLog("Inside FAULTHIsSupported:Could not find wininet.dll or determine version.");
  432. return( FALSE);
  433. }
  434. pInfo = HeapAlloc( GetProcessHeap(), 0, dwInfoSize);
  435. if( !pInfo ||
  436. !GetFileVersionInfo( FAULTH_WININET_NAME, dwTemp, dwInfoSize, pInfo) ||
  437. !VerQueryValue( pInfo, "\\", &VsInfo, &DataLength))
  438. {
  439. DebugLog("Inside FAULTHIsSupported:Could not find wininet.dll or get version.");
  440. HeapFree( GetProcessHeap(), 0, pInfo);
  441. return( FALSE);
  442. }
  443. if( VsInfo->dwFileVersionMS < FAULTH_WININET_MIN_MS ||
  444. ((VsInfo->dwFileVersionMS == FAULTH_WININET_MIN_MS) && (VsInfo->dwFileVersionLS < FAULTH_WININET_MIN_LS))) {
  445. DebugLog("Inside FAULTHIsSupported:Require a more recent wininet.dll.");
  446. HeapFree( GetProcessHeap(), 0, pInfo);
  447. return( FALSE);
  448. }
  449. HeapFree( GetProcessHeap(), 0, pInfo);
  450. return(TRUE);
  451. }
  452. static
  453. void
  454. FAULTHSetURLA(
  455. IN PSETUP_FAULT_HANDLER This,
  456. IN PCSTR pszURL
  457. )
  458. {
  459. DebugLog("Inside FAULTHSetURLA\r\n");
  460. if (This && pszURL){
  461. lstrcpynA( This->szURL, pszURL, DW_MAX_SERVERNAME);
  462. }
  463. }
  464. static
  465. void
  466. FAULTHSetURLW(
  467. IN PSETUP_FAULT_HANDLER This,
  468. IN PCWSTR pwzURL
  469. )
  470. {
  471. DebugLog("Inside FAULTHSetURLW\r\n");
  472. if (This && pwzURL){
  473. WideCharToMultiByte( CP_ACP, 0, pwzURL, -1, This->szURL, DW_MAX_SERVERNAME, NULL, NULL);
  474. }
  475. }
  476. static
  477. void
  478. FAULTHSetErrorTextA(
  479. IN PSETUP_FAULT_HANDLER This,
  480. IN PCSTR pszErrorText
  481. )
  482. {
  483. DebugLog("Inside FAULTHSetErrorTextA\r\n");
  484. if (This && pszErrorText){
  485. MultiByteToWideChar( CP_ACP, 0, pszErrorText, -1, This->wzErrorText, DW_MAX_ERROR_CWC);
  486. }
  487. }
  488. static
  489. void
  490. FAULTHSetErrorTextW(
  491. IN PSETUP_FAULT_HANDLER This,
  492. IN PCWSTR pwzErrorText
  493. )
  494. {
  495. DebugLog("Inside FAULTHSetErrorTextW\r\n");
  496. if (This && pwzErrorText){
  497. plstrcpynW( This->wzErrorText, pwzErrorText, DW_MAX_ERROR_CWC);
  498. }
  499. }
  500. static
  501. void
  502. FAULTHSetAdditionalFilesA(
  503. IN PSETUP_FAULT_HANDLER This,
  504. IN PCSTR pszAdditionalFiles
  505. )
  506. {
  507. DebugLog("Inside FAULTHSetAdditionalFilesA\r\n");
  508. if (This && pszAdditionalFiles){
  509. MultiByteToWideChar( CP_ACP, 0, pszAdditionalFiles, -1, This->wzAdditionalFiles, DW_MAX_ADDFILES);
  510. }
  511. }
  512. static
  513. void
  514. FAULTHSetAdditionalFilesW(
  515. IN PSETUP_FAULT_HANDLER This,
  516. IN PCWSTR pwzAdditionalFiles
  517. )
  518. {
  519. DebugLog("Inside FAULTHSetAdditionalFilesW\r\n");
  520. if (This && pwzAdditionalFiles){
  521. plstrcpynW( This->wzAdditionalFiles, pwzAdditionalFiles, DW_MAX_ADDFILES);
  522. }
  523. }
  524. static
  525. void
  526. FAULTHSetAppNameA(
  527. IN PSETUP_FAULT_HANDLER This,
  528. IN PCSTR pszAppName
  529. )
  530. {
  531. DebugLog("Inside FAULTHAppNameA\r\n");
  532. if (This && pszAppName){
  533. MultiByteToWideChar( CP_ACP, 0, pszAppName, -1, This->wzAppName, DW_APPNAME_LENGTH);
  534. }
  535. }
  536. static
  537. void
  538. FAULTHSetAppNameW(
  539. IN PSETUP_FAULT_HANDLER This,
  540. IN PCWSTR pwzAppName
  541. )
  542. {
  543. DebugLog("Inside FAULTHAppNameW\r\n");
  544. if (This && pwzAppName){
  545. plstrcpynW( This->wzAppName, pwzAppName, DW_APPNAME_LENGTH);
  546. }
  547. }
  548. static
  549. void
  550. FAULTHSetLCID(
  551. IN PSETUP_FAULT_HANDLER This,
  552. IN LCID lcid
  553. )
  554. {
  555. DebugLog("Inside FAULTHSetLCID\r\n");
  556. if (This){
  557. This->lcid = lcid;
  558. }
  559. }
  560. static
  561. VOID
  562. FAULTHInit(
  563. IN PSETUP_FAULT_HANDLER This
  564. )
  565. {
  566. DebugLog("Inside FAULTHInit\r\n");
  567. if( This){
  568. This->SetURLA = FAULTHSetURLA;
  569. This->SetURLW = FAULTHSetURLW;
  570. This->SetAppNameA = FAULTHSetAppNameA;
  571. This->SetAppNameW = FAULTHSetAppNameW;
  572. This->SetErrorTextA = FAULTHSetErrorTextA;
  573. This->SetErrorTextW = FAULTHSetErrorTextW;
  574. This->SetAdditionalFilesA = FAULTHSetAdditionalFilesA;
  575. This->SetAdditionalFilesW = FAULTHSetAdditionalFilesW;
  576. This->SetLCID = FAULTHSetLCID;
  577. This->IsSupported = FAULTHIsSupported;
  578. This->Report = FaultHandler;
  579. This->bDebug = FALSE;
  580. FAULTHSetURLA(This, c_szDWDefServerI);
  581. FAULTHSetAppNameW(This, c_wzDWDefAppName);
  582. FAULTHSetAdditionalFilesW(This, L"");
  583. FAULTHSetErrorTextW(This,L"");
  584. FAULTHSetLCID(This,c_DWDefaultLCID);
  585. }
  586. #ifdef TEST_WATSON
  587. {
  588. char szFile[MAX_PATH], *pwsz;
  589. GetSystemDirectoryA(szFile, sizeof(szFile)/sizeof(szFile[0]));
  590. szFile[3] = '\0';
  591. strcat(szFile, c_wszLogFileName);
  592. hFaultLog = CreateFileA(szFile, GENERIC_WRITE,
  593. FILE_SHARE_WRITE | FILE_SHARE_READ,
  594. NULL, OPEN_ALWAYS, 0, NULL);
  595. if (hFaultLog != INVALID_HANDLE_VALUE)
  596. {
  597. SYSTEMTIME st;
  598. DWORD cb, cbWritten;
  599. char szMsg[512];
  600. GetSystemTime(&st);
  601. cb = wsprintf(szMsg,
  602. "%02d-%02d-%04d %02d:%02d:%02d Initalization\r\n",
  603. st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute,
  604. st.wSecond);
  605. SetFilePointer(hFaultLog, 0, NULL, FILE_END);
  606. WriteFile(hFaultLog, szMsg, cb, &cbWritten, NULL);
  607. }
  608. }
  609. DebugLog("exiting FAULTHInit\r\n");
  610. #endif
  611. }
  612. PSETUP_FAULT_HANDLER APIENTRY
  613. FAULTHCreate( VOID)
  614. {
  615. PSETUP_FAULT_HANDLER This = NULL;
  616. DebugLog("Inside FAULTHCreate\r\n");
  617. This = HeapAlloc( GetProcessHeap(), 0, sizeof(SETUP_FAULT_HANDLER));
  618. if( This) {
  619. FAULTHInit( This);
  620. }
  621. DebugLog("exiting FAULTCreate\r\n");
  622. return This;
  623. }
  624. VOID APIENTRY
  625. FAULTHDelete(
  626. IN PSETUP_FAULT_HANDLER This
  627. )
  628. {
  629. DebugLog("Inside FAULTHDelete\r\n");
  630. if( This) {
  631. HeapFree( GetProcessHeap(), 0, This);
  632. }
  633. #ifdef TEST_WATSON
  634. if (hFaultLog != INVALID_HANDLE_VALUE) {
  635. CloseHandle(hFaultLog);
  636. }
  637. #endif
  638. }