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.

2881 lines
92 KiB

  1. /*++
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name: Oca_Extension
  4. Abstract: This Isapi extensions is used to provide a realtime interface
  5. from the OCA web site and the Analysis Servers.
  6. */
  7. //
  8. // Includes
  9. //
  10. #include <windows.h>
  11. #include <httpext.h>
  12. #include <stdio.h>
  13. #include <malloc.h>
  14. #include <objbase.h>
  15. #include <mqoai.h>
  16. #include <mq.h>
  17. #include <TCHAR.h>
  18. #include <Rpcdce.h>
  19. #include <strsafe.h>
  20. #include <process.h>
  21. #include <time.h>
  22. #include <dbgeng.h> // for crdb.h
  23. #include "messages.h"
  24. #include "ErrorCodes.h"
  25. #include "..\..\..\..\exts\extdll\crdb.h" // for source type definitions
  26. typedef struct Isapi_Params
  27. {
  28. wchar_t OutQueueConStr1[MAX_PATH];
  29. wchar_t OutQueueConStr2[MAX_PATH];
  30. wchar_t InQueueConStr1[MAX_PATH];
  31. // wchar_t InQueueConStr2[MAX_PATH];
  32. TCHAR WatsonBaseDir[MAX_PATH]; // Watson server to get file from
  33. TCHAR LocalBaseDir[MAX_PATH]; // Local machine directory to store dump file.
  34. TCHAR LocalShareName[MAX_PATH];
  35. TCHAR ErrorUrl[MAX_PATH];
  36. TCHAR ManualUploadPath[MAX_PATH]; // Upload location for manual submissions
  37. BOOL bAllowSR; // Process request of type CiSrcManualPssSr
  38. } ISAPI_PARAMS, * PISAPIPARAMS;
  39. /*
  40. winnt.h:#define EVENTLOG_SUCCESS 0x0000
  41. winnt.h:#define EVENTLOG_ERROR_TYPE 0x0001
  42. winnt.h:#define EVENTLOG_WARNING_TYPE 0x0002
  43. winnt.h:#define EVENTLOG_INFORMATION_TYPE 0x0004
  44. winnt.h:#define EVENTLOG_AUDIT_SUCCESS 0x0008
  45. winnt.h:#define EVENTLOG_AUDIT_FAILURE 0x0010
  46. */
  47. typedef enum _ISAPI_EVENT_TYPE {
  48. INFO = EVENTLOG_INFORMATION_TYPE,
  49. WARN = EVENTLOG_WARNING_TYPE,
  50. ERR = EVENTLOG_ERROR_TYPE,
  51. SUCCESS = EVENTLOG_SUCCESS,
  52. AUDIT_SUCCESS = EVENTLOG_AUDIT_SUCCESS,
  53. AUDIT_FAIL = EVENTLOG_AUDIT_FAILURE
  54. } ISAPI_EVENT_TYPE;
  55. #define LOGLEVEL_ALWAYS 0x00001
  56. #define LOGLEVEL_PERF 0x00100
  57. #define LOGLEVEL_DEBUG 0x01000
  58. #define LOGLEVEL_TRACE 0x10000
  59. //
  60. // Global Variables
  61. //
  62. TCHAR g_cszDefaultExtensionDll[] = _T("Oca_Extension.dll");
  63. const int NUMBEROFPROPERTIES = 5;
  64. long g_dwThreadCount = 0;
  65. BOOL bInitialized = FALSE;
  66. long MaxThreadCount = 100;
  67. CRITICAL_SECTION SendCritSec;
  68. ISAPI_PARAMS g_IsapiParams;
  69. DWORD g_dwDebugMode = LOGLEVEL_ALWAYS;
  70. DWORD g_dwProcessID = 0;
  71. PSID g_psidUser = NULL;
  72. HANDLE g_hEventSource = INVALID_HANDLE_VALUE;
  73. HMODULE g_hModule = NULL;
  74. TCHAR g_szAppName[MAX_PATH];
  75. //
  76. // Function Prototypes
  77. //
  78. unsigned int __stdcall WorkerFunction( void *vECB);
  79. BOOL SendHttpHeaders(EXTENSION_CONTROL_BLOCK *, LPCSTR , LPCSTR, BOOL );
  80. //HRESULT ConnectToMSMQ(QUEUEHANDLE *hQueue, wchar_t *QueueConnectStr, BOOL bSendAccess);
  81. int GetRegData(PISAPIPARAMS pParams);
  82. void LogEvent(DWORD dwLevel, ISAPI_EVENT_TYPE emType, DWORD dwEventID, DWORD dwErrorID, ...);
  83. void LogEventWithString(DWORD dwLevel, ISAPI_EVENT_TYPE emType, DWORD dwEventID, LPCTSTR pFormat, ...);
  84. DWORD SetupEventLog ( BOOL fSetup );
  85. //
  86. // Function Implementations.
  87. //
  88. BOOL WINAPI
  89. GetExtensionVersion(
  90. OUT HSE_VERSION_INFO *pVer
  91. )
  92. /*++
  93. Purpose:
  94. This is required ISAPI Extension DLL entry point.
  95. Arguments:
  96. pVer - points to extension version info structure
  97. Returns:
  98. always returns TRUE
  99. --*/
  100. {
  101. HANDLE hToken;
  102. TOKEN_USER *puser;
  103. DWORD cb = 0;
  104. DWORD dwResult = 0;
  105. int *test = NULL;
  106. free (test);
  107. LogEventWithString(LOGLEVEL_TRACE, INFO, ISAPI_EVENT_DEBUG, "GetExtensionVersion()");
  108. //
  109. // tell the server our version number and extension description
  110. //
  111. ZeroMemory(&g_IsapiParams, sizeof ISAPI_PARAMS);
  112. if (GetRegData (&g_IsapiParams))
  113. bInitialized = TRUE;
  114. else
  115. bInitialized = FALSE;
  116. SetupEventLog(TRUE);
  117. InitializeCriticalSection(&SendCritSec);
  118. pVer->dwExtensionVersion =
  119. MAKELONG( HSE_VERSION_MINOR, HSE_VERSION_MAJOR );
  120. g_dwProcessID = GetCurrentProcessId();
  121. /*
  122. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "GetExtensionVersion() - getting user SID");
  123. if (OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &hToken)
  124. || OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken))
  125. {
  126. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "GetExtensionVersion() - opened token");
  127. GetTokenInformation(hToken, TokenUser, NULL, cb, &cb);
  128. //puser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
  129. puser = (PTOKEN_USER)LocalAlloc(LPTR, cb);
  130. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "GetExtensionVersion() - token requires %d bytes, puser = %08x", cb, (DWORD_PTR)puser);
  131. if (puser && GetTokenInformation(hToken, TokenUser, puser, cb, &cb))
  132. {
  133. g_psidUser = puser->User.Sid;
  134. //HeapFree(GetProcessHeap(), 0, (LPVOID)puser);
  135. LocalFree(puser);
  136. }
  137. }
  138. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "GetExtensionVersion() - got user SID");
  139. */
  140. lstrcpyn(
  141. pVer->lpszExtensionDesc,
  142. "OCA Extension",
  143. HSE_MAX_EXT_DLL_NAME_LEN
  144. );
  145. LogEvent(
  146. LOGLEVEL_ALWAYS,
  147. SUCCESS,
  148. ISAPI_EVENT_SUCCESS_INITIALIZED,
  149. ISAPI_M_SUCCESS_INITIALIZED
  150. );
  151. return TRUE;
  152. }
  153. BOOL ParseQueryString(
  154. EXTENSION_CONTROL_BLOCK *pECB ,
  155. TCHAR *FileName,
  156. ULONG cbFileName,
  157. int * piType,
  158. TCHAR *szType,
  159. ULONG cbType,
  160. TCHAR *szSR,
  161. ULONG cbSR
  162. )
  163. {
  164. TCHAR *pFname = NULL;
  165. TCHAR *pQueryString = NULL;
  166. ULONG iCharCount = 0;
  167. TCHAR *pType = NULL;
  168. HRESULT hResult = S_OK;
  169. BOOL fRetVal = FALSE;
  170. LogEventWithString(
  171. LOGLEVEL_TRACE,
  172. INFO,
  173. ISAPI_EVENT_TRACE,
  174. "ParseQueryString(pECB, FileName=%s, *piType=%d, szType=%s)\r\n"
  175. "pECB->lpszQueryString: %s",
  176. FileName,
  177. *piType,
  178. szType,
  179. pECB->lpszQueryString
  180. );
  181. pFname = FileName;
  182. pQueryString = pECB->lpszQueryString;
  183. //--> Parse the string if it does not exactly match the following format dump the string
  184. //--> and send the client to the oca home page.
  185. // The url we are parsing must have the following format:
  186. /*
  187. id=3_20_2002\62018831_2.cab&
  188. Cab=/UploadBlue/62018831.cab&
  189. AutoLaunch=1&
  190. Client=BlueScreen&
  191. Old=1&
  192. BCCode=1000008e&
  193. BCP1=C0000005&
  194. BCP2=BFA00062&
  195. BCP3=EF8AEAFC&
  196. BCP4=00000000&
  197. OSVer=5_1_2600&
  198. SP=0_0&
  199. Product=256_1&
  200. LCID=1033
  201. */
  202. if (*pQueryString == _T('\0'))
  203. {
  204. LogEventWithString(
  205. LOGLEVEL_TRACE,
  206. INFO,
  207. ISAPI_EVENT_TRACE,
  208. "ParseQueryString() - pQueryString is empty string"
  209. );
  210. goto ERRORS;
  211. }
  212. // first lets make sure the query string starts with id=
  213. if ( ( (*pQueryString == _T('i')) || (*pQueryString == _T('I')) ) && (*(pQueryString +2) == _T('=')) )
  214. {
  215. ULONG cchFileName = cbFileName / sizeof(TCHAR);
  216. // ok so far move past the = character.
  217. pQueryString += 3;
  218. //Now get the cab file name.
  219. iCharCount = 0;
  220. while ((*pQueryString != _T('&')) && (*pQueryString != _T('\0')) && (iCharCount < cchFileName -1 ))
  221. {
  222. *pFname = *pQueryString;
  223. ++pFname;
  224. ++pQueryString;
  225. ++ iCharCount;
  226. // Null Terminate the fileName
  227. }
  228. FileName[cchFileName -1] = _T('\0');
  229. if (*pQueryString != _T('\0'))
  230. {
  231. // now see what type of upload this is.
  232. // Type = 5 is manual
  233. // Type = 6 is stress
  234. // Default is no type parameter and then the type is set to 0.
  235. ++ pQueryString;
  236. if ( (*pQueryString == _T('T')) || (*pQueryString == _T('t')) )
  237. {
  238. while ( (*pQueryString != _T('\0')) && (*pQueryString != _T('e')) && (*pQueryString != _T('E')) )
  239. {
  240. ++pQueryString;
  241. }
  242. if (*pQueryString != _T('\0'))
  243. {
  244. // We have the type parameter.
  245. // now strip off the designator and save it in iType.
  246. pType = szType;
  247. *pType = _T(';');
  248. ++pType;
  249. pQueryString+=2; // skip the e and the =
  250. iCharCount = 0;
  251. while ( (*pQueryString != _T('\0')) && (*pQueryString != _T('&')) && (iCharCount <3))
  252. {
  253. ++iCharCount;
  254. *pType = *pQueryString;
  255. ++pType;
  256. ++pQueryString;
  257. }
  258. // Null terminate the szType;
  259. *pType = _T('\0');
  260. pType = szType;
  261. ++pType; // skip the ;
  262. *piType = atoi(pType);
  263. }
  264. else
  265. {
  266. // we ran into a problem set the type to 0
  267. hResult = StringCbCopy(szType,cbType, _T(";1"));
  268. *piType = 1;
  269. if (FAILED (hResult))
  270. {
  271. goto ERRORS;
  272. }
  273. }
  274. }
  275. else
  276. {
  277. *piType = 1;
  278. hResult = StringCbCopy(szType,cbType, _T(";1"));
  279. if (FAILED (hResult))
  280. {
  281. goto ERRORS;
  282. }
  283. }
  284. }
  285. else
  286. {
  287. *piType = 1;
  288. hResult = StringCbCopy(szType,cbType, _T(";1"));
  289. if (FAILED (hResult))
  290. {
  291. goto ERRORS;
  292. }
  293. }
  294. if (*pQueryString == _T('&') && *piType == CiSrcManualPssSr)
  295. {
  296. // Check if we have a SR attached in query string
  297. if (!_tcsnicmp(pQueryString, _T("&SR="), 4))
  298. {
  299. // Copy the SR
  300. if (cbSR != 0)
  301. {
  302. ++pQueryString;
  303. cbSR -= sizeof(TCHAR);
  304. *szSR = _T(';');
  305. }
  306. while (*pQueryString != _T('\0') && *pQueryString != _T('&') &&
  307. cbSR > sizeof(TCHAR))
  308. {
  309. *szSR = *pQueryString;
  310. ++szSR; ++pQueryString;
  311. cbSR -= sizeof(TCHAR);
  312. }
  313. }
  314. }
  315. if (cbSR != 0)
  316. {
  317. *szSR = _T('\0');
  318. }
  319. fRetVal = TRUE;
  320. }
  321. ERRORS:
  322. LogEventWithString(
  323. LOGLEVEL_TRACE,
  324. INFO,
  325. ISAPI_EVENT_TRACE,
  326. "Exiting ParseQueryString(pECB, FileName=%s, *piType=%d, szType=%s)\r\n"
  327. "pQueryString: %s\r\n"
  328. "fRetVal: %d\r\n",
  329. FileName,
  330. *piType,
  331. szType,
  332. pQueryString,
  333. fRetVal
  334. );
  335. return fRetVal;
  336. }
  337. DWORD WINAPI
  338. HttpExtensionProc(
  339. IN EXTENSION_CONTROL_BLOCK *pECB
  340. )
  341. /*++
  342. Purpose:
  343. Create a thread to handle extended processing. It will be passed
  344. the address of a function ("WorkerFunction") to run, and the address
  345. of the ECB associated with this session.
  346. Arguments:
  347. pECB - pointer to the extenstion control block
  348. Returns:
  349. HSE_STATUS_PENDING to mark this request as pending
  350. --*/
  351. {
  352. UINT dwThreadID;
  353. HANDLE hThread;
  354. //HANDLE hToken;
  355. DWORD dwSize = 0;
  356. TCHAR FinalURL[MAX_PATH];
  357. TCHAR FileName[MAX_PATH];
  358. int iType =1;
  359. TCHAR szType [20];
  360. TCHAR szSR [50];
  361. char szHeader[] = "Content-type: text/html\r\n\r\n";
  362. TCHAR ErrorText[255];
  363. LogEventWithString(LOGLEVEL_TRACE, INFO, ISAPI_EVENT_TRACE, "HttpExtensionProc()");
  364. ZeroMemory(ErrorText,sizeof ErrorText);
  365. if (bInitialized)
  366. {
  367. if (g_dwThreadCount < MaxThreadCount)
  368. {
  369. hThread = NULL;
  370. hThread = (HANDLE)_beginthreadex(NULL, // Pointer to thread security attributes
  371. 0, // Initial thread stack size, in bytes
  372. &WorkerFunction, // Pointer to thread function
  373. pECB, // The ECB is the argument for the new thread
  374. 0, // Creation flags
  375. &dwThreadID // Pointer to returned thread identifier
  376. );
  377. //
  378. // update global thread count
  379. //
  380. InterlockedIncrement( &g_dwThreadCount );
  381. LogEventWithString(
  382. LOGLEVEL_DEBUG,
  383. SUCCESS,
  384. ISAPI_EVENT_DEBUG,
  385. "HttpExtensionProc() - started thread #%ld",
  386. g_dwThreadCount
  387. );
  388. // Return HSE_STATUS_PENDING to release IIS pool thread without losing connection
  389. if ((hThread) && (INVALID_HANDLE_VALUE != hThread))
  390. {
  391. CloseHandle(hThread);
  392. return HSE_STATUS_PENDING;
  393. }
  394. else
  395. {
  396. LogEventWithString(
  397. LOGLEVEL_ALWAYS,
  398. ERR,
  399. ISAPI_EVENT_ERROR,
  400. "HttpExtensionProc() - thread creation for thread #%ld failed",
  401. g_dwThreadCount
  402. );
  403. }
  404. }
  405. else
  406. {
  407. LogEventWithString(
  408. LOGLEVEL_ALWAYS,
  409. ERR,
  410. ISAPI_EVENT_PERF,
  411. "HttpExtensionProc() - exceeded max thread count #%ld",
  412. MaxThreadCount
  413. );
  414. }
  415. if ( (!ParseQueryString(pECB, FileName, sizeof(FileName), &iType,
  416. szType, sizeof(szType),
  417. szSR, sizeof(szSR))) && (iType == 1) )
  418. {
  419. ZeroMemory (FinalURL,sizeof FinalURL);
  420. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&State=0&Code=%d", g_IsapiParams.ErrorUrl,EXCEEDED_MAX_THREAD_COUNT) == S_OK)
  421. {
  422. LogEventWithString(
  423. LOGLEVEL_DEBUG,
  424. WARN,
  425. ISAPI_EVENT_WARNING,
  426. "HttpExtensionProc() - ParseQueryString() failed or iType=0\r\n"
  427. "FileName: %s\r\n"
  428. "iType: %d\r\n"
  429. "szType%s\r\n"
  430. "URL: %s",
  431. FileName,
  432. iType,
  433. szType,
  434. FinalURL
  435. );
  436. dwSize = (DWORD)_tcslen(FinalURL);
  437. pECB->ServerSupportFunction(pECB->ConnID,
  438. HSE_REQ_SEND_URL_REDIRECT_RESP,
  439. FinalURL,
  440. &dwSize,
  441. NULL
  442. );
  443. // TODO: log event if error
  444. }
  445. else
  446. {
  447. LogEventWithString(
  448. LOGLEVEL_ALWAYS,
  449. ERR,
  450. ISAPI_EVENT_ERROR,
  451. "HttpExtensionProc() - StringCbPrintf() failed"
  452. );
  453. // There is nothing we can do
  454. return HSE_STATUS_ERROR;
  455. }
  456. }
  457. else // Parsing succeeded
  458. {
  459. // Write the data to the client
  460. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&State=0&Code=%d", g_IsapiParams.ErrorUrl, EXCEEDED_MAX_THREAD_COUNT) == S_OK)
  461. {
  462. LogEventWithString(
  463. LOGLEVEL_TRACE,
  464. SUCCESS,
  465. ISAPI_EVENT_TRACE,
  466. "HttpExtensionProc() - ParseQueryString() succeeded (debug), StringCbPrintf succeeded\r\n"
  467. "FileName: %s\r\n"
  468. "iType: %d\r\n"
  469. "szType: %s\r\n"
  470. "ErrorText: %s",
  471. FileName,
  472. iType,
  473. szType,
  474. ErrorText
  475. );
  476. }
  477. else
  478. {
  479. LogEventWithString(
  480. LOGLEVEL_DEBUG,
  481. ERR,
  482. ISAPI_EVENT_ERROR,
  483. "HttpExtensionProc() - ParseQueryString() succeeded (debug), StringCbPrintf failed\r\n"
  484. "FileName: %s\r\n"
  485. "iType: %d\r\n"
  486. "szType: %s\r\n"
  487. "ErrorText: %s",
  488. FileName,
  489. iType,
  490. szType,
  491. ErrorText
  492. );
  493. return HSE_STATUS_ERROR;
  494. }
  495. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&State=0&Code=%d", g_IsapiParams.ErrorUrl, EXCEEDED_MAX_THREAD_COUNT) == S_OK)
  496. {
  497. if (StringCbCat(FinalURL, sizeof FinalURL, ErrorText) != S_OK)
  498. {
  499. LogEventWithString(
  500. LOGLEVEL_ALWAYS,
  501. ERR,
  502. ISAPI_EVENT_ERROR,
  503. "HttpExtensionProc() - ParseQueryString() succeeded (debug), StringCbCat failed\r\n"
  504. "FinalURL: %s\r\n"
  505. "ErrorText: %s",
  506. FinalURL,
  507. ErrorText
  508. );
  509. return HSE_STATUS_ERROR;
  510. }
  511. LogEventWithString(
  512. LOGLEVEL_DEBUG,
  513. SUCCESS,
  514. ISAPI_EVENT_DEBUG,
  515. "HttpExtensionProc() - ParseQueryString() succeeded (debug), StringCbPrintf succeeded\r\n"
  516. "URL: %s\r\n"
  517. "iType: %d\r\n"
  518. "szType: %s\r\n"
  519. "ErrorText: %s",
  520. FileName,
  521. iType,
  522. szType,
  523. FinalURL
  524. );
  525. // We want to write the response url to the client
  526. SendHttpHeaders( pECB, "200 OK", szHeader, FALSE );
  527. dwSize = (DWORD)strlen( FinalURL );
  528. pECB->WriteClient( pECB->ConnID, FinalURL, &dwSize, 0 );
  529. // TODO: add event logging if error
  530. }
  531. else
  532. {
  533. LogEventWithString(
  534. LOGLEVEL_ALWAYS,
  535. ERR,
  536. ISAPI_EVENT_ERROR,
  537. "HttpExtensionProc() - ParseQueryString() succeeded, StringCbPrintf failed\r\n"
  538. "FinalURL: %s\r\n",
  539. FinalURL
  540. );
  541. return HSE_STATUS_ERROR;
  542. }
  543. }
  544. }
  545. return HSE_STATUS_SUCCESS;
  546. }
  547. BOOL WINAPI
  548. TerminateExtension(
  549. IN DWORD dwFlags
  550. )
  551. /*++
  552. Routine Description:
  553. This function is called when the WWW service is shutdown.
  554. Arguments:
  555. dwFlags - HSE_TERM_ADVISORY_UNLOAD or HSE_TERM_MUST_UNLOAD
  556. Return Value:
  557. TRUE when extension is ready to be unloaded,
  558. --*/
  559. {
  560. LogEventWithString(LOGLEVEL_TRACE, INFO, ISAPI_EVENT_TRACE, "TerminateExtension()");
  561. //
  562. // wait for all threads to terminate, sleeping for 1 sec
  563. //
  564. DWORD dwSize = 0;
  565. if (dwFlags)
  566. {
  567. ;
  568. }
  569. while( g_dwThreadCount > 0 )
  570. {
  571. SleepEx( 1000, FALSE );
  572. }
  573. // Delete the critical sections
  574. DeleteCriticalSection(&SendCritSec);
  575. //
  576. // make sure the last thread indeed exited
  577. //
  578. SleepEx( 1000, FALSE );
  579. LogEvent(LOGLEVEL_ALWAYS, SUCCESS, ISAPI_EVENT_SUCCESS_EXITING, ISAPI_M_SUCCESS_EXITING);
  580. if (INVALID_HANDLE_VALUE != g_hEventSource)
  581. {
  582. DeregisterEventSource(g_hEventSource);
  583. }
  584. SetupEventLog(FALSE);
  585. //Disconnect from queue's and db if necessary.
  586. return TRUE;
  587. }
  588. BOOL GetRegData(PISAPIPARAMS pParams)
  589. /*++
  590. Routine Description:
  591. This function is called when the WWW service is shutdown.
  592. Arguments:
  593. dwFlags - HSE_TERM_ADVISORY_UNLOAD or HSE_TERM_MUST_UNLOAD
  594. Return Value:
  595. TRUE when extension is ready to be unloaded,
  596. --*/
  597. {
  598. HKEY hHKLM;
  599. HKEY hExtensionKey;
  600. BYTE Buffer[MAX_PATH * sizeof wchar_t];
  601. DWORD Type;
  602. DWORD BufferSize = MAX_PATH * sizeof wchar_t; // Set for largest value
  603. LogEventWithString(LOGLEVEL_TRACE, INFO, ISAPI_EVENT_TRACE, "GetRegData()");
  604. BOOL Status = FALSE;
  605. if(!RegConnectRegistry(NULL, HKEY_LOCAL_MACHINE, &hHKLM))
  606. {
  607. if(!RegOpenKeyEx(hHKLM,_T("Software\\Microsoft\\OCA_EXTENSION"), 0, KEY_ALL_ACCESS, &hExtensionKey))
  608. {
  609. // Get the input queue directory path
  610. if (RegQueryValueExW(hExtensionKey,L"OutgoingQueue1", 0, &Type, Buffer, &BufferSize) != ERROR_SUCCESS)
  611. {
  612. // LogEvent(_T("Failed to get InputQueue value from registry. Useing c:\\ as the default"));
  613. Status = FALSE;
  614. goto ERROR1;
  615. }
  616. else
  617. {
  618. if (StringCbCopyW (pParams->OutQueueConStr1,sizeof pParams->OutQueueConStr1, (wchar_t *) Buffer) != S_OK)
  619. {
  620. Status = FALSE;
  621. goto ERROR1;
  622. }
  623. BufferSize = MAX_PATH * sizeof wchar_t;
  624. ZeroMemory(Buffer, BufferSize);
  625. }
  626. // Get the input queue for full dumps
  627. if (RegQueryValueExW(hExtensionKey,L"OutgoingQueue2", 0, &Type, Buffer, &BufferSize) != ERROR_SUCCESS)
  628. {
  629. // LogEvent(_T("Failed to get InputQueue value from registry. Useing c:\\ as the default"));
  630. Status = FALSE;
  631. goto ERROR1;
  632. }
  633. else
  634. {
  635. if (StringCbCopyW (pParams->OutQueueConStr2,sizeof pParams->OutQueueConStr2, (wchar_t *) Buffer) != S_OK)
  636. {
  637. Status = FALSE;
  638. goto ERROR1;
  639. }
  640. BufferSize = MAX_PATH * sizeof wchar_t;
  641. ZeroMemory(Buffer, BufferSize);
  642. }
  643. // Now get the Win2kDSN
  644. if ( RegQueryValueExW(hExtensionKey,L"IncommingQueue1", 0, &Type, Buffer, &BufferSize) != ERROR_SUCCESS )
  645. {
  646. Status = FALSE;
  647. goto ERROR1;
  648. }
  649. else
  650. {
  651. if (StringCbCopyW(pParams->InQueueConStr1,sizeof pParams->InQueueConStr1, (wchar_t *) Buffer) != S_OK)
  652. {
  653. Status = FALSE;
  654. goto ERROR1;
  655. }
  656. BufferSize = MAX_PATH * sizeof wchar_t;
  657. ZeroMemory(Buffer, BufferSize);
  658. }
  659. // Now get the Win2kDSN
  660. if ( RegQueryValueEx(hExtensionKey,"ManualUploadPath", 0, &Type, Buffer, &BufferSize) != ERROR_SUCCESS )
  661. {
  662. Status = FALSE;
  663. goto ERROR1;
  664. }
  665. else
  666. {
  667. if (StringCbCopy(pParams->ManualUploadPath,sizeof pParams->ManualUploadPath, (TCHAR*) Buffer) != S_OK)
  668. {
  669. Status = FALSE;
  670. goto ERROR1;
  671. }
  672. BufferSize = MAX_PATH * sizeof wchar_t;
  673. ZeroMemory(Buffer, BufferSize);
  674. }
  675. // Get the input queue directory path
  676. /* if (RegQueryValueExW(hExtensionKey,L"OutgoingQueue2", 0, &Type, Buffer, &BufferSize) != ERROR_SUCCESS)
  677. {
  678. // LogEvent(_T("Failed to get InputQueue value from registry. Useing c:\\ as the default"));
  679. Status = FALSE;
  680. goto ERROR1;
  681. }
  682. else
  683. {
  684. if (StringCbCopyW (pParams->OutQueueConStr2,sizeof pParams->OutQueueConStr2, (wchar_t *) Buffer) != S_OK)
  685. {
  686. Status = FALSE;
  687. goto ERROR1;
  688. }
  689. BufferSize = MAX_PATH * sizeof wchar_t;
  690. ZeroMemory(Buffer, BufferSize);
  691. }
  692. */
  693. // Now get the Win2kDSN
  694. /* if ( RegQueryValueExW(hExtensionKey,L"IncommingQueue2", 0, &Type, Buffer, &BufferSize))
  695. {
  696. Status = FALSE;
  697. goto ERROR1;
  698. }
  699. else
  700. {
  701. if (StringCbCopyW(pParams->InQueueConStr2,sizeof pParams->InQueueConStr2, (wchar_t *) Buffer) != S_OK)
  702. {
  703. Status = FALSE;
  704. goto ERROR1;
  705. }
  706. BufferSize = MAX_PATH * sizeof wchar_t;
  707. ZeroMemory(Buffer, BufferSize);
  708. }
  709. */ // Now get the Win2kDSN
  710. if ( RegQueryValueEx(hExtensionKey,_T("WatsonBaseDir"), 0, &Type, Buffer, &BufferSize))
  711. {
  712. Status = FALSE;
  713. goto ERROR1;
  714. }
  715. else
  716. {
  717. if (StringCbCopy(pParams->WatsonBaseDir,sizeof pParams->WatsonBaseDir, (TCHAR *) Buffer) != S_OK)
  718. {
  719. Status = FALSE;
  720. goto ERROR1;
  721. }
  722. BufferSize = MAX_PATH * sizeof wchar_t;
  723. ZeroMemory(Buffer, BufferSize);
  724. }
  725. if ( RegQueryValueEx(hExtensionKey,_T("LocalBaseDir"), 0, &Type, Buffer, &BufferSize))
  726. {
  727. Status = FALSE;
  728. goto ERROR1;
  729. }
  730. else
  731. {
  732. if (StringCbCopy(pParams->LocalBaseDir,sizeof pParams->LocalBaseDir,(TCHAR *) Buffer) != S_OK)
  733. {
  734. Status = FALSE;
  735. goto ERROR1;
  736. }
  737. BufferSize = MAX_PATH * sizeof wchar_t;
  738. ZeroMemory(Buffer, BufferSize);
  739. }
  740. if ( RegQueryValueEx(hExtensionKey,_T("LocalShareName"), 0, &Type, Buffer, &BufferSize))
  741. {
  742. Status = FALSE;
  743. goto ERROR1;
  744. }
  745. else
  746. {
  747. if (StringCbCopy(pParams->LocalShareName,sizeof pParams->LocalShareName, (TCHAR *) Buffer) != S_OK)
  748. {
  749. Status = FALSE;
  750. goto ERROR1;
  751. }
  752. BufferSize = MAX_PATH * sizeof wchar_t;
  753. ZeroMemory(Buffer, BufferSize);
  754. }
  755. if ( RegQueryValueEx(hExtensionKey,_T("MaxThreadCount"), 0, &Type, Buffer, &BufferSize))
  756. {
  757. Status = FALSE;
  758. goto ERROR1;
  759. }
  760. else
  761. {
  762. MaxThreadCount = *((long*)Buffer);
  763. BufferSize = MAX_PATH * sizeof wchar_t;
  764. ZeroMemory(Buffer, BufferSize);
  765. }
  766. if ( RegQueryValueEx(hExtensionKey,_T("AllowSR"), 0, &Type, Buffer, &BufferSize))
  767. {
  768. pParams->bAllowSR = FALSE;
  769. }
  770. else
  771. {
  772. pParams->bAllowSR = *((BOOL*)Buffer);
  773. BufferSize = MAX_PATH * sizeof wchar_t;
  774. ZeroMemory(Buffer, BufferSize);
  775. }
  776. if ( RegQueryValueEx(hExtensionKey,_T("Debug"), 0, &Type, Buffer, &BufferSize))
  777. {
  778. Status = FALSE;
  779. goto ERROR1;
  780. }
  781. else
  782. {
  783. g_dwDebugMode = *((DWORD*)Buffer);
  784. BufferSize = MAX_PATH * sizeof wchar_t;
  785. ZeroMemory(Buffer, BufferSize);
  786. }
  787. if ( RegQueryValueEx(hExtensionKey,_T("ErrorUrl"), 0, &Type, Buffer, &BufferSize))
  788. {
  789. Status = FALSE;
  790. goto ERROR1;
  791. }
  792. else
  793. {
  794. if (StringCbCopy(g_IsapiParams.ErrorUrl,sizeof g_IsapiParams.ErrorUrl, (TCHAR *) Buffer) != S_OK)
  795. {
  796. Status = FALSE;
  797. goto ERROR1;
  798. }
  799. BufferSize = MAX_PATH * sizeof wchar_t;
  800. ZeroMemory(Buffer, BufferSize);
  801. }
  802. RegCloseKey(hExtensionKey);
  803. RegCloseKey(hHKLM);
  804. return TRUE;
  805. }
  806. else
  807. {
  808. RegCloseKey(hHKLM);
  809. return FALSE;
  810. }
  811. }
  812. else
  813. {
  814. return FALSE;
  815. }
  816. ERROR1:
  817. if (hExtensionKey)
  818. RegCloseKey(hExtensionKey);
  819. if (hHKLM)
  820. RegCloseKey(hHKLM);
  821. LogEventWithString(LOGLEVEL_TRACE, INFO, ISAPI_EVENT_TRACE, "Exiting GetRegData()\r\nreturn value: %d", (int)Status);
  822. return Status;
  823. }
  824. BOOL SendQueueMessage(QUEUEHANDLE hOutgoingQueue, wchar_t *MessageGuid, wchar_t *FilePath)
  825. {
  826. MQMSGPROPS msgProps;
  827. MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  828. MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  829. HRESULT aMsgStatus[NUMBEROFPROPERTIES];
  830. DWORD cPropId = 0;
  831. BOOL Status = TRUE;
  832. HRESULT hResult = S_OK;
  833. char szGuid[512];
  834. char szPath[512];
  835. LogEventWithString(LOGLEVEL_TRACE, INFO, ISAPI_EVENT_TRACE, "SendQueueMessage()");
  836. if ( (!MessageGuid ) || (!FilePath))
  837. {
  838. wcstombs( szGuid, MessageGuid, sizeof(MessageGuid)/sizeof(MessageGuid[0]) );
  839. wcstombs( szPath, FilePath, sizeof(FilePath)/sizeof(FilePath[0]) );
  840. LogEvent(
  841. LOGLEVEL_ALWAYS,
  842. ERR,
  843. ISAPI_EVENT_ERROR_INVALID_SEND_PARAMS,
  844. ISAPI_M_ERROR_INVALID_SEND_PARAMS,
  845. (MessageGuid != NULL) ? szGuid : _T(""),
  846. (FilePath != NULL) ? szPath : _T("")
  847. );
  848. Status = FALSE;
  849. }
  850. else
  851. {
  852. aMsgPropId [cPropId] = PROPID_M_LABEL; // Property ID.
  853. aMsgPropVar[cPropId].vt = VT_LPWSTR; // Type indicator.
  854. aMsgPropVar[cPropId].pwszVal = MessageGuid; // The message label.
  855. cPropId++;
  856. aMsgPropId [cPropId] = PROPID_M_BODY;
  857. aMsgPropVar [cPropId].vt = VT_VECTOR|VT_UI1;
  858. aMsgPropVar [cPropId].caub.pElems = (LPBYTE) FilePath;
  859. aMsgPropVar [cPropId].caub.cElems = (DWORD) wcslen(FilePath)* 2;
  860. cPropId++;
  861. aMsgPropId [cPropId] = PROPID_M_BODY_TYPE;
  862. aMsgPropVar[cPropId].vt = VT_UI4;
  863. aMsgPropVar[cPropId].ulVal = (DWORD) VT_BSTR;
  864. cPropId++;
  865. // Initialize the MQMSGPROPS structure.
  866. msgProps.cProp = cPropId;
  867. msgProps.aPropID = aMsgPropId;
  868. msgProps.aPropVar = aMsgPropVar;
  869. msgProps.aStatus = aMsgStatus;
  870. //
  871. // Send it
  872. //
  873. hResult = MQSendMessage(
  874. hOutgoingQueue, // Queue handle.
  875. &msgProps, // Message property structure.
  876. MQ_NO_TRANSACTION // No transaction.
  877. );
  878. if (FAILED(hResult))
  879. {
  880. wcstombs(szGuid,MessageGuid, wcslen(MessageGuid) *2);
  881. wcstombs(szPath,FilePath, wcslen(FilePath) *2);
  882. LogEvent(
  883. LOGLEVEL_ALWAYS,
  884. ERR,
  885. ISAPI_EVENT_ERROR_CANNOT_SEND,
  886. ISAPI_M_ERROR_CANNOT_SEND,
  887. szGuid,
  888. szPath,
  889. hResult
  890. );
  891. Status = FALSE;
  892. }
  893. }
  894. LogEventWithString(
  895. LOGLEVEL_TRACE,
  896. INFO,
  897. ISAPI_EVENT_TRACE,
  898. "Exiting SendQueueMessage()\r\n"
  899. "return value: %d",
  900. (int)Status
  901. );
  902. return Status;
  903. }
  904. unsigned int __stdcall
  905. WorkerFunction(
  906. void *vECB
  907. )
  908. /*++
  909. Purpose:
  910. This Function performs all of the Message queueing for realtime processing
  911. with out tying up the IIS process threads.
  912. Arguments:
  913. vECB - points to current extension control block
  914. Returns:
  915. returns 0
  916. --*/
  917. {
  918. char szHeader[] = "Content-type: text/html\r\n\r\n";
  919. EXTENSION_CONTROL_BLOCK *pECB;
  920. HRESULT hResult = S_OK;
  921. GUID MessageGuid;
  922. TCHAR DestinationDir[MAX_PATH];
  923. TCHAR *pQueryString = NULL;
  924. TCHAR *pFname = NULL;
  925. TCHAR CurrentFileName[MAX_PATH];
  926. TCHAR SourceDir[MAX_PATH];
  927. HANDLE hToken = INVALID_HANDLE_VALUE;
  928. wchar_t wszMessageGuid[100];
  929. TCHAR szMessageGuid[200];
  930. wchar_t *szTempMessageGuid = NULL;
  931. DWORD dwSize = 0;
  932. wchar_t DestinationPath[MAX_PATH];
  933. wchar_t RecMessageBody[255];
  934. TCHAR szRecMessageBody[255];
  935. UINT RetryCount = 0;
  936. BOOL Status = TRUE;
  937. BOOL bReadFromPrimary = TRUE;
  938. int ErrorCode = 0;
  939. TCHAR *temp = NULL;
  940. TCHAR RedirURL[MAX_PATH];
  941. DWORD dwDestSize = 0;
  942. TCHAR szType[10];
  943. TCHAR szSR[50];
  944. int iCharCount = 0;
  945. TCHAR *pType = NULL;
  946. int iType = 1;
  947. TCHAR FinalURL[MAX_PATH];
  948. int iState = 0;
  949. wchar_t *temp2 = NULL;
  950. HANDLE hManualFile = INVALID_HANDLE_VALUE;
  951. TCHAR TestDestination[MAX_PATH];
  952. DWORD CharCount = 0;
  953. TCHAR ErrorText[255];
  954. TCHAR PerfText[MAX_PATH];
  955. // Recieve message vars
  956. MSGPROPID PropIds[5];
  957. MQPROPVARIANT PropVariants[5];
  958. HRESULT hrProps[5];
  959. MQMSGPROPS MessageProps;
  960. DWORD i = 0;
  961. wchar_t RecLabel[100];
  962. wchar_t LocalRecBody[255];
  963. DWORD RecMessageBodySize = sizeof LocalRecBody;
  964. DWORD RecLabelLength = sizeof RecLabel;
  965. HANDLE hCursor = INVALID_HANDLE_VALUE;
  966. BOOL MessageFound = FALSE;
  967. time_t Start;
  968. time_t Stop;
  969. DWORD StartSendQueue = 0, StopSendQueue = 0;
  970. DWORD StartRecvQueue = 0, StopRecvQueue = 0;
  971. DWORD StartThread= 0, StopThread = 0;
  972. DWORD ElapsedTimeThread = 0, ElapsedTimeSendQueue = 0, ElapsedTimeRecvQueue;
  973. BOOL CursorValid = FALSE;
  974. BOOL fFullDump = FALSE;
  975. StartThread = GetTickCount();
  976. // Queue Handles
  977. QUEUEHANDLE hPrimaryInQueue = NULL;
  978. QUEUEHANDLE hPrimaryOutQueue = NULL;
  979. // QUEUEHANDLE hSecondaryInQueue = NULL;
  980. // QUEUEHANDLE hSecondaryOutQueue = NULL;
  981. LogEventWithString(
  982. LOGLEVEL_DEBUG,
  983. INFO,
  984. ISAPI_EVENT_DEBUG,
  985. "WorkerFunction()\r\n"
  986. "Last Error: %08x\r\n"
  987. "TID: %ld\r\n",
  988. GetLastError(),
  989. GetCurrentThreadId()
  990. );
  991. // Clear the strings
  992. ZeroMemory(DestinationPath, sizeof DestinationPath);
  993. ZeroMemory(RecMessageBody, sizeof RecMessageBody);
  994. ZeroMemory(szMessageGuid, sizeof szMessageGuid);
  995. ZeroMemory(RedirURL, sizeof RedirURL);
  996. ZeroMemory(FinalURL, sizeof FinalURL);
  997. ZeroMemory(wszMessageGuid, sizeof wszMessageGuid);
  998. ZeroMemory(DestinationDir, sizeof DestinationDir);
  999. ZeroMemory(TestDestination, sizeof TestDestination);
  1000. ZeroMemory(ErrorText, sizeof ErrorText);
  1001. ZeroMemory(PerfText, sizeof PerfText);
  1002. ZeroMemory(CurrentFileName, sizeof CurrentFileName);
  1003. ZeroMemory(SourceDir, sizeof SourceDir);
  1004. ZeroMemory(szRecMessageBody, sizeof szRecMessageBody);
  1005. ZeroMemory(szType, sizeof szType);
  1006. //
  1007. // Initialize local ECB pointer to void pointer passed to thread
  1008. //
  1009. LogEventWithString(
  1010. LOGLEVEL_DEBUG,
  1011. INFO,
  1012. ISAPI_EVENT_DEBUG,
  1013. "WorkerFunction()\r\n"
  1014. "Calling pECB->ServerSupportFunction\r\n"
  1015. "Last Error: %08lx",
  1016. GetLastError()
  1017. );
  1018. pECB = (EXTENSION_CONTROL_BLOCK *)vECB;
  1019. Status = pECB->ServerSupportFunction(
  1020. pECB->ConnID,
  1021. HSE_REQ_GET_IMPERSONATION_TOKEN,
  1022. &hToken,
  1023. NULL,
  1024. NULL
  1025. );
  1026. LogEventWithString(
  1027. LOGLEVEL_DEBUG,
  1028. INFO,
  1029. ISAPI_EVENT_DEBUG,
  1030. "WorkerFunction()\r\n"
  1031. "Called pECB->ServerSupportFunction\r\n"
  1032. "Status: %d\r\n"
  1033. "hToken: %08x\r\n"
  1034. "Last Error: %08lx",
  1035. Status,
  1036. (DWORD_PTR)hToken,
  1037. GetLastError()
  1038. );
  1039. // TODO: handle error if returned
  1040. if ( !ImpersonateLoggedOnUser(hToken))
  1041. {
  1042. // We failed to impersonate the user. We Cannot continue.
  1043. LogEvent(
  1044. LOGLEVEL_ALWAYS,
  1045. ERR,
  1046. ISAPI_EVENT_ERROR_CANT_IMPERSONATE,
  1047. ISAPI_M_ERROR_CANT_IMPERSONATE,
  1048. GetLastError()
  1049. );
  1050. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"), FAILED_TO_IMPERSONATE_USER) != S_OK)
  1051. {
  1052. LogEventWithString(
  1053. LOGLEVEL_ALWAYS,
  1054. ERR,
  1055. ISAPI_EVENT_ERROR,
  1056. "WorkerFunction() - StringCbPrintf() failed\r\n"
  1057. "hToken: %08x\r\n",
  1058. (DWORD_PTR)hToken
  1059. );
  1060. }
  1061. goto ERRORS;
  1062. }
  1063. //
  1064. //Get filename from parameter list.
  1065. //
  1066. ZeroMemory (CurrentFileName,sizeof CurrentFileName);
  1067. //
  1068. // Get the file name from the query string.
  1069. //
  1070. if ( (!ParseQueryString(pECB, CurrentFileName, sizeof(CurrentFileName), &iType,
  1071. szType, sizeof(szType),
  1072. szSR, sizeof(szSR)) ))
  1073. {
  1074. LogEventWithString(
  1075. LOGLEVEL_ALWAYS,
  1076. WARN,
  1077. ISAPI_EVENT_WARNING,
  1078. "WorkerFunction() - ParseQueryString() failed\r\n"
  1079. "CurrentFileName: %s\r\n"
  1080. "iType: %d\r\n"
  1081. "szType%s",
  1082. CurrentFileName,
  1083. iType,
  1084. szType
  1085. );
  1086. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"),FAILED_TO_PARSE_QUERYSTRING ) != S_OK)
  1087. {
  1088. LogEventWithString(
  1089. LOGLEVEL_ALWAYS,
  1090. ERR,
  1091. ISAPI_EVENT_ERROR,
  1092. "WorkerFunction() - StringCbPrintf() failed"
  1093. );
  1094. }
  1095. goto ERRORS;
  1096. }
  1097. LogEventWithString(
  1098. LOGLEVEL_DEBUG,
  1099. INFO,
  1100. ISAPI_EVENT_DEBUG,
  1101. "WorkerFunction() - ParseQueryString() succeeded\r\n"
  1102. "CurrentFileName: %s\r\n"
  1103. "iType: %d\r\n"
  1104. "szType%s",
  1105. CurrentFileName,
  1106. iType,
  1107. szType
  1108. );
  1109. //
  1110. // Copy File Localy
  1111. // Note this needs to be removed when the client uploads the file
  1112. // Directly to our servers.
  1113. //
  1114. // build the source file name.
  1115. switch (iType)
  1116. {
  1117. case CiSrcErClient:
  1118. if (StringCbPrintf(SourceDir,sizeof SourceDir, _T("%s\\%s"), g_IsapiParams.WatsonBaseDir, CurrentFileName) != S_OK)
  1119. {
  1120. LogEventWithString(
  1121. LOGLEVEL_ALWAYS,
  1122. ERR,
  1123. ISAPI_EVENT_ERROR,
  1124. "WorkerFunction() - StringCbPrintf() failed"
  1125. );
  1126. Status = FALSE;
  1127. goto ERRORS;
  1128. }
  1129. /* if (StringCbPrintf(DestinationDir,sizeof DestinationDir, _T("%s\\%s"), g_IsapiParams.LocalBaseDir,CurrentFileName) != S_OK)
  1130. {
  1131. LogEventWithString(
  1132. LOGLEVEL_ALWAYS,
  1133. ERR,
  1134. ISAPI_EVENT_ERROR,
  1135. "WorkerFunction() - StringCbPrintf() failed"
  1136. );
  1137. Status = FALSE;
  1138. goto ERRORS;
  1139. }
  1140. */
  1141. break;
  1142. case CiSrcManualFullDump:
  1143. fFullDump = TRUE;
  1144. iType = CiSrcManual;
  1145. if (StringCbPrintf(szType, sizeof(szType), _T(";%ld"), iType) != S_OK)
  1146. {
  1147. // Failure is harmless, debugger will consider these 2 types as the same
  1148. iType = CiSrcManualFullDump;
  1149. }
  1150. // fall through
  1151. case CiSrcCER:
  1152. case CiSrcManual:
  1153. case CiSrcStress:
  1154. break;
  1155. case CiSrcManualPssSr:
  1156. fFullDump = TRUE; // we want to process these same way as fulldumps
  1157. break;
  1158. default: // invalid type specified
  1159. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"),INVALID_TYPE_SPECIFIED) != S_OK)
  1160. {
  1161. LogEventWithString(
  1162. LOGLEVEL_ALWAYS,
  1163. ERR,
  1164. ISAPI_EVENT_ERROR,
  1165. "WorkerFunction() - StringCbPrintf() failed"
  1166. );
  1167. }
  1168. LogEventWithString(
  1169. LOGLEVEL_DEBUG,
  1170. ERR,
  1171. ISAPI_EVENT_DEBUG,
  1172. "WorkerFunction() - unknown iType specified\r\n"
  1173. "iType: %d",
  1174. iType
  1175. );
  1176. goto ERRORS;
  1177. }
  1178. // Now change the date file name \ to an _ note this only works for the date\filename format
  1179. /* if ((iType != 5) && (iType != 6))
  1180. {
  1181. dwDestSize = (DWORD) _tcslen(DestinationDir);
  1182. if (dwDestSize >0)
  1183. {
  1184. temp = DestinationDir + _tcslen(DestinationDir);
  1185. while ((*temp != '\\') && (*temp != '/'))
  1186. -- temp;
  1187. if ((*temp == '\\') || (*temp == '/'))
  1188. *temp = '_';
  1189. }
  1190. else
  1191. {
  1192. LogEventWithString(
  1193. LOGLEVEL_DEBUG,
  1194. ERR,
  1195. ISAPI_EVENT_DEBUG,
  1196. "WorkerFunction() - dwDestSize = 0"
  1197. );
  1198. Status = FALSE;
  1199. goto ERRORS;
  1200. }
  1201. if (!CopyFile (SourceDir, DestinationDir, FALSE) )
  1202. {
  1203. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"),FAILED_TO_COPY_FILE) != S_OK)
  1204. {
  1205. LogEventWithString(
  1206. LOGLEVEL_ALWAYS,
  1207. ERR,
  1208. ISAPI_EVENT_ERROR,
  1209. "WorkerFunction() - StringCbPrintf() failed"
  1210. );
  1211. }
  1212. LogEvent(LOGLEVEL_ALWAYS, WARN, ISAPI_EVENT_WARNING_FILE_COPY_FAILED, ISAPI_M_WARNING_FILE_COPY_FAILED, SourceDir, DestinationDir, GetLastError());
  1213. Status = FALSE;
  1214. goto ERRORS;
  1215. }
  1216. }
  1217. */
  1218. //ZeroMemory (DestinationDir, sizeof DestinationDir);
  1219. /*
  1220. if ((iType != 5) && (iType != 6))
  1221. {
  1222. if (_tcslen(CurrentFileName) > 0)
  1223. {
  1224. temp = CurrentFileName + _tcslen(CurrentFileName);
  1225. while ( (*temp != '\\') && (*temp != '/') && (temp!= CurrentFileName) )
  1226. -- temp;
  1227. if ((*temp == '\\') || (*temp == '/'))
  1228. *temp = '_';
  1229. }
  1230. else
  1231. {
  1232. LogEventWithString(
  1233. LOGLEVEL_DEBUG,
  1234. ERR,
  1235. ISAPI_EVENT_DEBUG,
  1236. "WorkerFunction() - _tcslen(CurrentFileName) = 0"
  1237. );
  1238. Status = FALSE;
  1239. goto ERRORS;
  1240. }
  1241. }
  1242. */
  1243. switch (iType)
  1244. {
  1245. case CiSrcErClient:
  1246. if (StringCbPrintf(DestinationDir, sizeof DestinationDir, _T("%s\\%s%s"), g_IsapiParams.WatsonBaseDir, CurrentFileName,szType)!= S_OK)
  1247. {
  1248. LogEventWithString(
  1249. LOGLEVEL_DEBUG,
  1250. ERR,
  1251. ISAPI_EVENT_DEBUG,
  1252. "WorkerFunction() - StringCbPrintf failed"
  1253. );
  1254. Status = FALSE;
  1255. goto ERRORS;
  1256. }
  1257. break;
  1258. case CiSrcManualFullDump: // Same as 5 but a full dump, send it off to a separate Q dedicated to fulldumps
  1259. iType = CiSrcManual;
  1260. // fall through
  1261. case CiSrcManualPssSr:
  1262. fFullDump = TRUE;
  1263. // fall through
  1264. case CiSrcCER:
  1265. case CiSrcManual:
  1266. case CiSrcStress:
  1267. if ((iType == CiSrcManualPssSr) && g_IsapiParams.bAllowSR)
  1268. {
  1269. hResult = StringCbPrintf(DestinationDir, sizeof DestinationDir, _T("%s\\%s%s;%s"),
  1270. g_IsapiParams.ManualUploadPath,CurrentFileName,szType,szSR);
  1271. } else
  1272. {
  1273. hResult = StringCbPrintf(DestinationDir, sizeof DestinationDir, _T("%s\\%s%s"),
  1274. g_IsapiParams.ManualUploadPath,CurrentFileName,szType);
  1275. }
  1276. if (hResult != S_OK)
  1277. {
  1278. LogEventWithString(
  1279. LOGLEVEL_DEBUG,
  1280. ERR,
  1281. ISAPI_EVENT_DEBUG,
  1282. "WorkerFunction() - StringCbPrintf failed"
  1283. );
  1284. Status = FALSE;
  1285. goto ERRORS;
  1286. }
  1287. else
  1288. {
  1289. // Check to see if the file exists
  1290. //
  1291. if (StringCbPrintf(TestDestination, sizeof TestDestination,_T("%s\\%s"), g_IsapiParams.ManualUploadPath,CurrentFileName)== S_OK)
  1292. {
  1293. hManualFile = CreateFile(TestDestination,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  1294. if (hManualFile == INVALID_HANDLE_VALUE)
  1295. {
  1296. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"),FILE_NOT_FOUND) != S_OK)
  1297. {
  1298. LogEventWithString(
  1299. LOGLEVEL_DEBUG,
  1300. ERR,
  1301. ISAPI_EVENT_DEBUG,
  1302. "WorkerFunction() - StringCbPrintf failed"
  1303. );
  1304. }
  1305. LogEvent(LOGLEVEL_ALWAYS, WARN, ISAPI_EVENT_WARNING_FILE_MISSING, ISAPI_M_WARNING_FILE_MISSING, TestDestination);
  1306. Status = FALSE;
  1307. goto ERRORS;
  1308. }
  1309. else
  1310. {
  1311. CloseHandle(hManualFile);
  1312. }
  1313. }
  1314. else
  1315. {
  1316. LogEventWithString(
  1317. LOGLEVEL_DEBUG,
  1318. ERR,
  1319. ISAPI_EVENT_DEBUG,
  1320. "WorkerFunction() - StringCbPrintf failed"
  1321. );
  1322. Status = FALSE;
  1323. goto ERRORS;
  1324. }
  1325. }
  1326. break;
  1327. #ifdef USE_OLD_STRESS_SOURCE
  1328. case 6:
  1329. if (StringCbPrintf(DestinationDir, sizeof DestinationDir, _T("%s%s"), CurrentFileName,szType)!= S_OK)
  1330. {
  1331. LogEventWithString(
  1332. LOGLEVEL_DEBUG,
  1333. ERR,
  1334. ISAPI_EVENT_DEBUG,
  1335. "WorkerFunction() - StringCbPrintf failed"
  1336. );
  1337. Status = FALSE;
  1338. goto ERRORS;
  1339. }
  1340. else
  1341. {
  1342. hManualFile = CreateFile(TestDestination,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  1343. if (hManualFile == INVALID_HANDLE_VALUE)
  1344. {
  1345. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"),FILE_NOT_FOUND) != S_OK)
  1346. {
  1347. LogEventWithString(
  1348. LOGLEVEL_DEBUG,
  1349. ERR,
  1350. ISAPI_EVENT_DEBUG,
  1351. "WorkerFunction() - StringCbPrintf failed"
  1352. );
  1353. }
  1354. LogEvent(LOGLEVEL_ALWAYS, WARN, ISAPI_EVENT_WARNING_FILE_MISSING, ISAPI_M_WARNING_FILE_MISSING, TestDestination);
  1355. Status = FALSE;
  1356. goto ERRORS;
  1357. }
  1358. else
  1359. {
  1360. CloseHandle(hManualFile);
  1361. }
  1362. }
  1363. break;
  1364. #endif // USE_OLD_STRESS_SOURCE
  1365. default: // Invalid Type
  1366. LogEventWithString(
  1367. LOGLEVEL_DEBUG,
  1368. ERR,
  1369. ISAPI_EVENT_DEBUG,
  1370. "WorkerFunction() - unknown iType specified\r\n"
  1371. "iType: %d",
  1372. iType
  1373. );
  1374. goto ERRORS;
  1375. }
  1376. ZeroMemory (DestinationPath, sizeof DestinationPath);
  1377. mbstowcs(DestinationPath,DestinationDir,_tcslen(DestinationDir));
  1378. //
  1379. // Generate Guid for this message
  1380. //
  1381. hResult = CoCreateGuid(&MessageGuid);
  1382. if (FAILED(hResult))
  1383. {
  1384. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"),FAILED_TO_CREATE_GUID) != S_OK)
  1385. {
  1386. LogEventWithString(
  1387. LOGLEVEL_ALWAYS,
  1388. ERR,
  1389. ISAPI_EVENT_ERROR,
  1390. "WorkerFunction() - StringCbPrintf failed"
  1391. );
  1392. }
  1393. LogEventWithString(
  1394. LOGLEVEL_ALWAYS,
  1395. ERR,
  1396. ISAPI_EVENT_ERROR,
  1397. "WorkerFunction() - CoCreateGuid failed\r\n"
  1398. "hResult: %08x",
  1399. hResult
  1400. );
  1401. goto ERRORS;
  1402. }
  1403. else
  1404. {
  1405. hResult = UuidToStringW(&MessageGuid, &szTempMessageGuid);
  1406. if (hResult == RPC_S_OK)
  1407. {
  1408. // Make a copy of the string quid then release it.
  1409. if (StringCbCopyW(wszMessageGuid,sizeof wszMessageGuid, szTempMessageGuid) != S_OK)
  1410. {
  1411. LogEvent(LOGLEVEL_ALWAYS, ERR, ISAPI_EVENT_ERROR_GUID_COPY, ISAPI_M_ERROR_GUID_COPY, szTempMessageGuid, wszMessageGuid, GetLastError());
  1412. goto ERRORS;
  1413. }
  1414. }
  1415. else
  1416. {
  1417. LogEventWithString(
  1418. LOGLEVEL_ALWAYS,
  1419. ERR,
  1420. ISAPI_EVENT_ERROR,
  1421. "WorkerFunction() - UuidToStringW failed\r\n"
  1422. "hResult: %08x\r\n"
  1423. "szTempMessageGuid: %s",
  1424. hResult,
  1425. szTempMessageGuid
  1426. );
  1427. // TODO: goto ERRORS?
  1428. }
  1429. }
  1430. //EnterCriticalSection(&SendCritSec);
  1431. StartSendQueue = GetTickCount();
  1432. // if connect to primary Receive
  1433. hResult = MQOpenQueue(g_IsapiParams.InQueueConStr1,
  1434. MQ_RECEIVE_ACCESS,
  1435. MQ_DENY_NONE,
  1436. &hPrimaryInQueue);
  1437. if (SUCCEEDED(hResult))
  1438. {
  1439. hResult = MQOpenQueue( (fFullDump ? g_IsapiParams.OutQueueConStr2 : g_IsapiParams.OutQueueConStr1),
  1440. MQ_SEND_ACCESS,
  1441. MQ_DENY_NONE,
  1442. &hPrimaryOutQueue);
  1443. if (SUCCEEDED(hResult))
  1444. {
  1445. EnterCriticalSection(&SendCritSec);
  1446. if( SendQueueMessage(hPrimaryOutQueue, wszMessageGuid, DestinationPath))
  1447. {
  1448. LogEventWithString(
  1449. LOGLEVEL_TRACE,
  1450. SUCCESS,
  1451. ISAPI_EVENT_TRACE,
  1452. "WorkerFunction() - SendQueueMessage() succeeded - using PrimaryOutQueue\r\n"
  1453. "hPrimaryOutQueue: %08x\r\n"
  1454. "wszMessageGuid: %s\r\n"
  1455. "DestinationPath: %s",
  1456. (DWORD_PTR)hPrimaryOutQueue,
  1457. wszMessageGuid,
  1458. DestinationPath
  1459. );
  1460. LeaveCriticalSection(&SendCritSec);
  1461. bReadFromPrimary = TRUE;
  1462. MQCloseQueue(hPrimaryOutQueue);
  1463. hPrimaryOutQueue = NULL;
  1464. }
  1465. else
  1466. {
  1467. LeaveCriticalSection(&SendCritSec);
  1468. LogEventWithString(
  1469. LOGLEVEL_DEBUG,
  1470. ERR,
  1471. ISAPI_EVENT_DEBUG,
  1472. "WorkerFunction() - SendQueueMessage() failed\r\n"
  1473. "hPrimaryOutQueue: %08x\r\n"
  1474. "wszMessageGuid: %s\r\n"
  1475. "DestinationPath: %s",
  1476. (DWORD_PTR)hPrimaryOutQueue,
  1477. wszMessageGuid,
  1478. DestinationPath
  1479. );
  1480. MQCloseQueue(hPrimaryInQueue);
  1481. MQCloseQueue(hPrimaryOutQueue);
  1482. goto ERRORS;
  1483. // This block is commented out because each web server now only has 1 message queue
  1484. /*
  1485. hResult = MQOpenQueue(g_IsapiParams.InQueueConStr2,
  1486. MQ_RECEIVE_ACCESS,
  1487. MQ_DENY_NONE,
  1488. &hPrimaryInQueue);
  1489. if (SUCCEEDED(hResult))
  1490. {
  1491. hResult = MQOpenQueue(g_IsapiParams.OutQueueConStr2,
  1492. MQ_SEND_ACCESS,
  1493. MQ_DENY_NONE,
  1494. &hSecondaryInQueue);
  1495. if (SUCCEEDED(hResult))
  1496. {
  1497. EnterCriticalSection(&SendCritSec);
  1498. if( SendQueueMessage(hSecondaryOutQueue, wszMessageGuid, DestinationPath))
  1499. {
  1500. LeaveCriticalSection(&SendCritSec);
  1501. bReadFromPrimary = FALSE;
  1502. MQCloseQueue(hPrimaryOutQueue);
  1503. hPrimaryOutQueue = NULL;
  1504. }
  1505. else
  1506. {
  1507. LeaveCriticalSection(&SendCritSec);
  1508. MQCloseQueue(hSecondaryInQueue);
  1509. MQCloseQueue(hSecondaryOutQueue);
  1510. hSecondaryInQueue = NULL;
  1511. hSecondaryOutQueue = NULL;
  1512. goto ERRORS;
  1513. }
  1514. }
  1515. else
  1516. {
  1517. MQCloseQueue(hSecondaryInQueue);
  1518. hSecondaryInQueue = NULL;
  1519. goto ERRORS;
  1520. }
  1521. }
  1522. else
  1523. {
  1524. goto ERRORS;
  1525. }
  1526. */
  1527. }
  1528. }
  1529. else // MQOpenQueue(g_IsapiParams.OutQueueConStr1,
  1530. {
  1531. LogEventWithString(
  1532. LOGLEVEL_ALWAYS,
  1533. ERR,
  1534. ISAPI_EVENT_ERROR,
  1535. "WorkerFunction() - MQOpenQueue(g_IsapiParams.OutQueueConStr1 ...) failed"
  1536. "hResult: %08x",
  1537. hResult
  1538. );
  1539. // This block is commented out because each web server now only has 1 message queue
  1540. /* MQCloseQueue(hPrimaryInQueue);
  1541. hResult = MQOpenQueue(g_IsapiParams.InQueueConStr2,
  1542. MQ_RECEIVE_ACCESS,
  1543. MQ_DENY_NONE,
  1544. &hPrimaryInQueue);
  1545. if (SUCCEEDED(hResult))
  1546. {
  1547. hResult = MQOpenQueue(g_IsapiParams.OutQueueConStr2,
  1548. MQ_SEND_ACCESS,
  1549. MQ_DENY_NONE,
  1550. &hSecondaryInQueue);
  1551. if (SUCCEEDED(hResult))
  1552. {
  1553. EnterCriticalSection(&SendCritSec);
  1554. if( SendQueueMessage(hSecondaryOutQueue, wszMessageGuid, DestinationPath))
  1555. {
  1556. LeaveCriticalSection(&SendCritSec);
  1557. bReadFromPrimary = FALSE;
  1558. MQCloseQueue(hPrimaryOutQueue);
  1559. hPrimaryOutQueue = NULL;
  1560. }
  1561. else
  1562. {
  1563. LeaveCriticalSection(&SendCritSec);
  1564. MQCloseQueue(hSecondaryInQueue);
  1565. MQCloseQueue(hSecondaryOutQueue);
  1566. hSecondaryInQueue = NULL;
  1567. hSecondaryOutQueue = NULL;
  1568. goto ERRORS;
  1569. }
  1570. }
  1571. else
  1572. {
  1573. MQCloseQueue(hSecondaryInQueue);
  1574. hSecondaryInQueue = NULL;
  1575. goto ERRORS;
  1576. }
  1577. }
  1578. else
  1579. {
  1580. goto ERRORS;
  1581. }
  1582. */
  1583. goto ERRORS;
  1584. }
  1585. }
  1586. else // MQOpenQueue(g_IsapiParams.InQueueConStr1,
  1587. {
  1588. LogEventWithString(
  1589. LOGLEVEL_ALWAYS,
  1590. ERR,
  1591. ISAPI_EVENT_ERROR,
  1592. "WorkerFunction() - MQOpenQueue(g_IsapiParams.InQueueConStr1 ...) failed"
  1593. "hResult: %08x",
  1594. hResult
  1595. );
  1596. // This block is commented out because each web server now only has 1 message queue
  1597. /* hResult = MQOpenQueue(g_IsapiParams.InQueueConStr2,
  1598. MQ_RECEIVE_ACCESS,
  1599. MQ_DENY_NONE,
  1600. &hPrimaryInQueue);
  1601. if (SUCCEEDED(hResult))
  1602. {
  1603. hResult = MQOpenQueue(g_IsapiParams.OutQueueConStr2,
  1604. MQ_SEND_ACCESS,
  1605. MQ_DENY_NONE,
  1606. &hSecondaryInQueue);
  1607. if (SUCCEEDED(hResult))
  1608. {
  1609. EnterCriticalSection(&SendCritSec);
  1610. if( SendQueueMessage(hSecondaryOutQueue, wszMessageGuid, DestinationPath))
  1611. {
  1612. LeaveCriticalSection(&SendCritSec);
  1613. bReadFromPrimary = FALSE;
  1614. MQCloseQueue(hPrimaryOutQueue);
  1615. hPrimaryOutQueue = NULL;
  1616. }
  1617. else
  1618. {
  1619. LeaveCriticalSection(&SendCritSec);
  1620. MQCloseQueue(hSecondaryInQueue);
  1621. MQCloseQueue(hSecondaryOutQueue);
  1622. hSecondaryInQueue = NULL;
  1623. hSecondaryOutQueue = NULL;
  1624. goto ERRORS;
  1625. }
  1626. }
  1627. else
  1628. {
  1629. MQCloseQueue(hSecondaryInQueue);
  1630. hSecondaryInQueue = NULL;
  1631. goto ERRORS;
  1632. }
  1633. }
  1634. else
  1635. {
  1636. goto ERRORS;
  1637. }
  1638. */
  1639. goto ERRORS;
  1640. }
  1641. StopSendQueue = GetTickCount();
  1642. //-------------------------------------------------------------------------------------------------
  1643. // Recieve the response from kd
  1644. //-------------------------------------------------------------------------------------------------
  1645. Sleep(1000); // give kd a chance to process the message.
  1646. Status = FALSE;
  1647. ZeroMemory(LocalRecBody,sizeof LocalRecBody);
  1648. ZeroMemory(RecLabel,sizeof RecLabel);
  1649. i = 0;
  1650. PropIds[i] = PROPID_M_LABEL_LEN;
  1651. PropVariants[i].vt = VT_UI4;
  1652. PropVariants[i].ulVal = RecLabelLength;
  1653. i++;
  1654. PropIds[i] = PROPID_M_LABEL;
  1655. PropVariants[i].vt = VT_LPWSTR;
  1656. PropVariants[i].pwszVal = RecLabel;
  1657. i++;
  1658. MessageProps.aPropID = PropIds;
  1659. MessageProps.aPropVar = PropVariants;
  1660. MessageProps.aStatus = hrProps;
  1661. MessageProps.cProp = i;
  1662. double TotalElapsedTime = 0.0;
  1663. StartRecvQueue = GetTickCount();
  1664. if ( (hResult = MQCreateCursor( /*(bReadFromPrimary == TRUE) ? */hPrimaryInQueue ,//: hSecondaryInQueue,
  1665. &hCursor))
  1666. != S_OK)
  1667. {
  1668. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"), FAILED_TO_CREATE_CURSOR)!= S_OK)
  1669. {
  1670. LogEventWithString(
  1671. LOGLEVEL_ALWAYS,
  1672. ERR,
  1673. ISAPI_EVENT_ERROR,
  1674. "WorkerFunction() - StringCbPrintf failed"
  1675. );
  1676. }
  1677. LogEvent(
  1678. LOGLEVEL_ALWAYS,
  1679. ERR,
  1680. ISAPI_EVENT_ERROR_CANNOT_CREATE_RECEIVE_CURSOR,
  1681. ISAPI_M_ERROR_CANNOT_CREATE_RECEIVE_CURSOR,
  1682. hResult,
  1683. (DWORD_PTR)hCursor
  1684. );
  1685. Status = FALSE;
  1686. goto ERRORS;
  1687. }
  1688. else
  1689. {
  1690. do {
  1691. CursorValid = TRUE;
  1692. // dwSize = _tcslen(_T("Starting Scan <BR>"));
  1693. // pECB->WriteClient(pECB->ConnID,_T("Starting Scan <BR>"),&dwSize,0);
  1694. // Peak at each member of the queue and return the label.
  1695. time(&Start);
  1696. hResult = MQReceiveMessage(/*(bReadFromPrimary == TRUE) ? */hPrimaryInQueue,// : hSecondaryInQueue, // Queue handle.
  1697. 20000, // Maximum time (msec) to read the message.
  1698. MQ_ACTION_PEEK_CURRENT, // Receive action.
  1699. &MessageProps, // Message property structure.
  1700. NULL, // No OVERLAPPED structure.
  1701. NULL, // No callback function.
  1702. hCursor, // Cursor handle.
  1703. NULL // No transaction.
  1704. );
  1705. time(&Stop);
  1706. TotalElapsedTime+= difftime(Stop,Start);
  1707. if (hResult == S_OK)
  1708. {
  1709. MessageFound = FALSE;
  1710. // There is a message in the queue.
  1711. // now see if it is the one we want.
  1712. // if the message was found retrieve it.
  1713. // Otherwise close the cursor and return false.
  1714. do
  1715. {
  1716. if (! _wcsicmp(RecLabel,wszMessageGuid))
  1717. {
  1718. MessageFound = TRUE;
  1719. }
  1720. else
  1721. {
  1722. // Not it Lets peek at the next one
  1723. time(&Start);
  1724. PropVariants[i].ulVal = RecLabelLength; // Reset the label buffer size.
  1725. hResult = MQReceiveMessage(/*(bReadFromPrimary == TRUE) ?*/ hPrimaryInQueue,// : hSecondaryInQueue, // Queue handle.
  1726. ((DWORD)(20.0 - TotalElapsedTime)) * 1000, // Maximum time (msec).
  1727. MQ_ACTION_PEEK_NEXT, // Receive action.
  1728. &MessageProps, // Message property structure.
  1729. NULL, // No OVERLAPPED structure.
  1730. NULL, // No callback function.
  1731. hCursor, // Cursor handle.
  1732. NULL // No transaction.
  1733. );
  1734. time(&Stop);
  1735. TotalElapsedTime += difftime(Stop, Start);
  1736. LogEventWithString(
  1737. LOGLEVEL_DEBUG,
  1738. ERR,
  1739. ISAPI_EVENT_DEBUG,
  1740. "WorkerFunction() - MQReceiveMessage(hPrimaryInQueue ...) failed (peek)\r\n"
  1741. "hResult: %08x",
  1742. hResult
  1743. );
  1744. }
  1745. } while ( (!MessageFound ) && (hResult == S_OK) && (TotalElapsedTime < 20.0));
  1746. if (!MessageFound)
  1747. {
  1748. Status = FALSE;
  1749. }
  1750. if (MessageFound)
  1751. {
  1752. // retrieve the current message
  1753. i = 0;
  1754. PropIds[i] = PROPID_M_LABEL_LEN;
  1755. PropVariants[i].vt = VT_UI4;
  1756. PropVariants[i].ulVal = RecLabelLength;
  1757. i++;
  1758. PropIds[i] = PROPID_M_LABEL;
  1759. PropVariants[i].vt = VT_LPWSTR;
  1760. PropVariants[i].pwszVal = RecLabel;
  1761. i++;
  1762. PropIds[i] = PROPID_M_BODY_SIZE;
  1763. PropVariants[i].vt = VT_UI4;
  1764. i++;
  1765. PropIds[i] = PROPID_M_BODY_TYPE;
  1766. PropVariants[i].vt = VT_UI4;
  1767. i++;
  1768. PropIds[i] = PROPID_M_BODY;
  1769. PropVariants[i].vt = VT_VECTOR|VT_UI1;
  1770. PropVariants[i].caub.pElems = (LPBYTE) LocalRecBody;
  1771. PropVariants[i].caub.cElems = RecMessageBodySize;
  1772. i++;
  1773. MessageProps.aPropID = PropIds;
  1774. MessageProps.aPropVar = PropVariants;
  1775. MessageProps.aStatus = hrProps;
  1776. MessageProps.cProp = i;
  1777. hResult = MQReceiveMessage(/*(bReadFromPrimary == TRUE) ? */hPrimaryInQueue,// : hSecondaryInQueue,
  1778. 0,
  1779. MQ_ACTION_RECEIVE,
  1780. &MessageProps,
  1781. NULL,
  1782. NULL,
  1783. hCursor,
  1784. MQ_NO_TRANSACTION);
  1785. if (FAILED (hResult) )
  1786. {
  1787. LogEventWithString(
  1788. LOGLEVEL_DEBUG,
  1789. ERR,
  1790. ISAPI_EVENT_DEBUG,
  1791. "WorkerFunction() - MQReceiveMessage(hPrimaryInQueue ...) failed (receive)\r\n"
  1792. "hResult: %08x",
  1793. hResult
  1794. );
  1795. Status = FALSE;
  1796. }
  1797. else
  1798. {
  1799. hResult = StringCbCopyW(RecMessageBody, RecMessageBodySize, LocalRecBody);
  1800. Status = TRUE;
  1801. }
  1802. }
  1803. else
  1804. {
  1805. Status = FALSE;
  1806. }
  1807. }
  1808. else
  1809. {
  1810. LogEventWithString(
  1811. LOGLEVEL_DEBUG,
  1812. ERR,
  1813. ISAPI_EVENT_DEBUG,
  1814. "WorkerFunction() - MQReceiveMessage(hSecondaryInQueue ...) failed\r\n"
  1815. "hResult: %08x",
  1816. hResult
  1817. );
  1818. if (hResult != MQ_ERROR_IO_TIMEOUT)
  1819. {
  1820. LogEvent(LOGLEVEL_ALWAYS, WARN, ISAPI_EVENT_WARNING_PEEK, ISAPI_M_WARNING_PEEK, hResult);
  1821. // attemp to re-connect to the queueu
  1822. /* if (bReadFromPrimary == TRUE)
  1823. {
  1824. */
  1825. hResult = MQOpenQueue(g_IsapiParams.InQueueConStr1,
  1826. MQ_RECEIVE_ACCESS,
  1827. MQ_DENY_NONE,
  1828. &hPrimaryInQueue);
  1829. if (FAILED(hResult))
  1830. {
  1831. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"), FAILED_RECONNECT_RECEIVE)!= S_OK)
  1832. {
  1833. LogEventWithString(
  1834. LOGLEVEL_ALWAYS,
  1835. ERR,
  1836. ISAPI_EVENT_ERROR,
  1837. "WorkerFunction() - StringCbPrintf failed"
  1838. );
  1839. }
  1840. LogEvent(LOGLEVEL_ALWAYS, ERR, ISAPI_EVENT_ERROR_RECONNECT, ISAPI_M_ERROR_RECONNECT, "primary receive queue", hResult);
  1841. goto ERRORS;
  1842. }
  1843. /*
  1844. }
  1845. else
  1846. {
  1847. hResult = MQOpenQueue(g_IsapiParams.InQueueConStr1,
  1848. MQ_RECEIVE_ACCESS,
  1849. MQ_DENY_NONE,
  1850. &hPrimaryInQueue);
  1851. if (FAILED(hResult))
  1852. {
  1853. LogEvent(LOGLEVEL_ALWAYS, ERR, ISAPI_EVENT_ERROR_RECONNECT, ISAPI_M_ERROR_RECONNECT, "secondary receive queue", hResult);
  1854. goto ERRORS;
  1855. }
  1856. }
  1857. */
  1858. }
  1859. else
  1860. {
  1861. LogEvent(LOGLEVEL_ALWAYS, WARN, ISAPI_EVENT_WARNING_TIMEOUT_EXPIRED, ISAPI_M_WARNING_TIMEOUT_EXPIRED);
  1862. }
  1863. }
  1864. // Close the cursor
  1865. if (CursorValid)
  1866. MQCloseCursor(hCursor);
  1867. } while ((TotalElapsedTime < 20.0) && (!MessageFound));
  1868. }
  1869. StopRecvQueue = GetTickCount();
  1870. StopThread = GetTickCount();
  1871. ElapsedTimeSendQueue = StopSendQueue - StartSendQueue;
  1872. ElapsedTimeRecvQueue = StopRecvQueue - StartRecvQueue;
  1873. ElapsedTimeThread = StopThread - StartThread;
  1874. if (g_dwDebugMode & LOGLEVEL_PERF)
  1875. {
  1876. if (StringCbPrintf(
  1877. PerfText,
  1878. sizeof(PerfText),
  1879. _T("&PerfThread=%ld&PerfSendQueue=%ld&PerfRecvQueue=%ld"),
  1880. ElapsedTimeThread,
  1881. ElapsedTimeSendQueue,
  1882. ElapsedTimeRecvQueue
  1883. ) != S_OK)
  1884. {
  1885. LogEventWithString(
  1886. LOGLEVEL_ALWAYS,
  1887. ERR,
  1888. ISAPI_EVENT_ERROR,
  1889. "WorkerFunction() - StringCbPrintf failed"
  1890. );
  1891. }
  1892. }
  1893. // Send the response url to the client
  1894. if (!Status)
  1895. {
  1896. if (StringCbPrintf(ErrorText,sizeof ErrorText,_T("&Code=%d"), MESSAGE_RECEIVE_TIMEOUT)!= S_OK)
  1897. {
  1898. LogEventWithString(
  1899. LOGLEVEL_ALWAYS,
  1900. ERR,
  1901. ISAPI_EVENT_ERROR,
  1902. "WorkerFunction() - StringCbPrintf failed"
  1903. );
  1904. }
  1905. goto ERRORS;
  1906. }
  1907. else
  1908. {
  1909. // Close the Receive queue
  1910. if (iType != 1)
  1911. {
  1912. SendHttpHeaders( pECB, "200 OK", szHeader, FALSE );
  1913. }
  1914. // convert the wchar message guid to a mbs string
  1915. wcstombs(szMessageGuid,wszMessageGuid,wcslen(wszMessageGuid) * sizeof wchar_t);
  1916. // Ok we have a message did we get a url ?
  1917. if (! _wcsicmp(RecMessageBody, L"NO_SOLUTION"))
  1918. {
  1919. // This should never happen but just in case send the error url with
  1920. // Tracking turned on Log the guid so we can followup later.
  1921. LogEvent(LOGLEVEL_ALWAYS, WARN, ISAPI_EVENT_WARNING_NO_SOLUTION, ISAPI_M_WARNING_NO_SOLUTION, szMessageGuid);
  1922. if (iType == 1)
  1923. {
  1924. // send the redirection command
  1925. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&State=1%s%s&ID=%s", g_IsapiParams.ErrorUrl,ErrorText,PerfText,szMessageGuid) == S_OK)
  1926. {
  1927. dwSize = (DWORD)_tcslen(FinalURL);
  1928. pECB->ServerSupportFunction(
  1929. pECB->ConnID,
  1930. HSE_REQ_SEND_URL_REDIRECT_RESP,
  1931. FinalURL,
  1932. &dwSize,
  1933. NULL
  1934. );
  1935. }
  1936. else
  1937. {
  1938. LogEventWithString(
  1939. LOGLEVEL_ALWAYS,
  1940. ERR,
  1941. ISAPI_EVENT_ERROR,
  1942. "WorkerFunction() - StringCbPrintf failed"
  1943. );
  1944. goto ERRORS;
  1945. }
  1946. }
  1947. else
  1948. {
  1949. // Write the response to the wininet client
  1950. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&State=1%s%s&ID=%s", g_IsapiParams.ErrorUrl,ErrorText,PerfText,szMessageGuid) == S_OK)
  1951. {
  1952. // We want to write the response url to the client
  1953. dwSize = (DWORD)strlen( FinalURL );
  1954. pECB->WriteClient( pECB->ConnID, FinalURL, &dwSize, 0 );
  1955. }
  1956. else
  1957. {
  1958. LogEventWithString(
  1959. LOGLEVEL_ALWAYS,
  1960. ERR,
  1961. ISAPI_EVENT_ERROR,
  1962. "WorkerFunction() - StringCbPrintf failed"
  1963. );
  1964. goto ERRORS;
  1965. }
  1966. }
  1967. }
  1968. else
  1969. {
  1970. temp2 = RecMessageBody;
  1971. temp2 += (wcslen(RecMessageBody)-1);
  1972. while ( (*temp2 != L'=') && (temp2 != RecMessageBody))
  1973. -- temp2;
  1974. // ok Temp + 1 is our new state value.
  1975. if (temp2 != RecMessageBody)
  1976. {
  1977. iState = _wtoi(temp2+1);
  1978. }
  1979. // Convert the message body to a TCHAR
  1980. wcstombs(szRecMessageBody,RecMessageBody,((wcslen(RecMessageBody)+1) * sizeof wchar_t));
  1981. if (iState == 1)
  1982. {
  1983. wcstombs(szMessageGuid,wszMessageGuid,((wcslen(wszMessageGuid)+1) * sizeof wchar_t));
  1984. if (iType == 1) // Watson Client or other web browser
  1985. {
  1986. // We want to send a redirection command to the client
  1987. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&ID=%s%s", szRecMessageBody,szMessageGuid,PerfText) == S_OK)
  1988. {
  1989. dwSize = (DWORD)_tcslen(FinalURL);
  1990. pECB->ServerSupportFunction(
  1991. pECB->ConnID,
  1992. HSE_REQ_SEND_URL_REDIRECT_RESP,
  1993. FinalURL,
  1994. &dwSize,
  1995. NULL
  1996. );
  1997. }
  1998. else
  1999. {
  2000. LogEventWithString(
  2001. LOGLEVEL_ALWAYS,
  2002. ERR,
  2003. ISAPI_EVENT_ERROR,
  2004. "WorkerFunction() - StringCbPrintf failed"
  2005. );
  2006. goto ERRORS;
  2007. }
  2008. }
  2009. else // WinInet Client
  2010. {
  2011. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&ID=%s%s", szRecMessageBody,szMessageGuid,PerfText) == S_OK)
  2012. {
  2013. // We want to write the response url to the client
  2014. dwSize = (DWORD)strlen( FinalURL );
  2015. pECB->WriteClient( pECB->ConnID, FinalURL, &dwSize, 0 );
  2016. }
  2017. else
  2018. {
  2019. LogEventWithString(
  2020. LOGLEVEL_ALWAYS,
  2021. ERR,
  2022. ISAPI_EVENT_ERROR,
  2023. "WorkerFunction() - StringCbPrintf failed"
  2024. );
  2025. goto ERRORS;
  2026. }
  2027. }
  2028. }
  2029. else // We have a real solution so DO NOT send the Guid
  2030. {
  2031. if (iType == 1)
  2032. {
  2033. //wcstombs(szMessageGuid,wszMessageGuid,((wcslen(wszMessageGuid)+1) * sizeof wchar_t));
  2034. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s%s", szRecMessageBody,PerfText) == S_OK)
  2035. {
  2036. dwSize = (DWORD)_tcslen(FinalURL);
  2037. pECB->ServerSupportFunction(
  2038. pECB->ConnID,
  2039. HSE_REQ_SEND_URL_REDIRECT_RESP,
  2040. FinalURL,
  2041. &dwSize,
  2042. NULL
  2043. );
  2044. }
  2045. else
  2046. {
  2047. LogEventWithString(
  2048. LOGLEVEL_ALWAYS,
  2049. ERR,
  2050. ISAPI_EVENT_ERROR,
  2051. "WorkerFunction() - StringCbPrintf failed"
  2052. );
  2053. goto ERRORS;
  2054. }
  2055. }
  2056. else
  2057. {
  2058. // write the response to the client
  2059. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s%s", szRecMessageBody,PerfText) == S_OK)
  2060. {
  2061. // We want to write the response url to the client
  2062. dwSize = (DWORD)strlen( FinalURL );
  2063. pECB->WriteClient( pECB->ConnID, FinalURL, &dwSize, 0 );
  2064. }
  2065. else
  2066. {
  2067. LogEventWithString(
  2068. LOGLEVEL_ALWAYS,
  2069. ERR,
  2070. ISAPI_EVENT_ERROR,
  2071. "WorkerFunction() - StringCbPrintf failed"
  2072. );
  2073. goto ERRORS;
  2074. }
  2075. }
  2076. }
  2077. }
  2078. }
  2079. if (szTempMessageGuid)
  2080. {
  2081. RpcStringFreeW(&szTempMessageGuid);
  2082. }
  2083. pECB->ServerSupportFunction(pECB->ConnID,
  2084. HSE_REQ_DONE_WITH_SESSION,
  2085. NULL,
  2086. NULL,
  2087. NULL
  2088. );
  2089. InterlockedDecrement(&g_dwThreadCount);
  2090. if (hPrimaryInQueue)
  2091. MQCloseQueue(hPrimaryInQueue);
  2092. // if (hSecondaryInQueue)
  2093. // MQCloseQueue(hSecondaryInQueue);
  2094. if (hPrimaryOutQueue)
  2095. MQCloseQueue(hPrimaryOutQueue);
  2096. // if (hSecondaryOutQueue)
  2097. // MQCloseQueue(hSecondaryOutQueue);
  2098. LogEventWithString(LOGLEVEL_TRACE, SUCCESS, ISAPI_EVENT_TRACE, "Exiting WorkerFunction(), no errors!");
  2099. _endthreadex(0);
  2100. return TRUE;
  2101. ERRORS:
  2102. if (0 == StartSendQueue)
  2103. StopSendQueue = 0;
  2104. else if (0 == StopSendQueue)
  2105. StopSendQueue = GetTickCount();
  2106. if (0 == StartRecvQueue)
  2107. StopRecvQueue = 0;
  2108. else if (0 == StopRecvQueue)
  2109. StopRecvQueue = GetTickCount();
  2110. StopThread = GetTickCount();
  2111. ElapsedTimeSendQueue = StopSendQueue - StartSendQueue;
  2112. ElapsedTimeRecvQueue = StopRecvQueue - StartRecvQueue;
  2113. ElapsedTimeThread = StopThread - StartThread;
  2114. if (g_dwDebugMode & LOGLEVEL_PERF)
  2115. {
  2116. if (StringCbPrintf(
  2117. PerfText,
  2118. sizeof(PerfText),
  2119. _T("&PerfThread=%ld&PerfSendQueue=%ld&PerfRecvQueue=%ld"),
  2120. ElapsedTimeThread,
  2121. ElapsedTimeSendQueue,
  2122. ElapsedTimeRecvQueue
  2123. ) != S_OK)
  2124. {
  2125. LogEventWithString(
  2126. LOGLEVEL_ALWAYS,
  2127. ERR,
  2128. ISAPI_EVENT_ERROR,
  2129. "WorkerFunction() - StringCbPrintf failed"
  2130. );
  2131. }
  2132. }
  2133. if (szTempMessageGuid)
  2134. {
  2135. RpcStringFreeW(&szTempMessageGuid);
  2136. }
  2137. if (iType == 1)
  2138. {
  2139. // We want to send a redirection command to the client
  2140. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&State=0%s%s", g_IsapiParams.ErrorUrl, ErrorText, PerfText) == S_OK)
  2141. {
  2142. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "WorkerFunction() - sending redirect\r\nFinalURL: %s", FinalURL);
  2143. dwSize = (DWORD)_tcslen(FinalURL);
  2144. pECB->ServerSupportFunction(
  2145. pECB->ConnID,
  2146. HSE_REQ_SEND_URL_REDIRECT_RESP,
  2147. FinalURL,
  2148. &dwSize,
  2149. NULL
  2150. );
  2151. }
  2152. }
  2153. else
  2154. {
  2155. // We want to write the response url to the client
  2156. // Write the response to the wininet client
  2157. if (StringCbPrintf(FinalURL, sizeof FinalURL, "%s&State=0%s%s", g_IsapiParams.ErrorUrl, ErrorText, PerfText) == S_OK)
  2158. {
  2159. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "WorkerFunction() - sending response\r\nFinalURL: %s", FinalURL);
  2160. // We want to write the response url to the client
  2161. SendHttpHeaders( pECB, "200 OK", szHeader, FALSE );
  2162. dwSize = (DWORD)strlen( FinalURL );
  2163. pECB->WriteClient( pECB->ConnID, FinalURL, &dwSize, 0 );
  2164. }
  2165. }
  2166. pECB->ServerSupportFunction(pECB->ConnID,
  2167. HSE_REQ_DONE_WITH_SESSION,
  2168. NULL,
  2169. NULL,
  2170. NULL
  2171. );
  2172. InterlockedDecrement(&g_dwThreadCount);
  2173. if (hPrimaryInQueue)
  2174. MQCloseQueue(hPrimaryInQueue);
  2175. // if (hSecondaryInQueue)
  2176. // MQCloseQueue(hSecondaryInQueue);
  2177. if (hPrimaryOutQueue)
  2178. MQCloseQueue(hPrimaryOutQueue);
  2179. // if (hSecondaryOutQueue)
  2180. // MQCloseQueue(hSecondaryOutQueue);
  2181. LogEventWithString(LOGLEVEL_TRACE, ERR, ISAPI_EVENT_TRACE, "Exiting WorkerFunction(), error occurred");
  2182. _endthreadex(0);
  2183. return TRUE;
  2184. }
  2185. BOOL
  2186. SendHttpHeaders(
  2187. EXTENSION_CONTROL_BLOCK *pECB,
  2188. LPCSTR pszStatus,
  2189. LPCSTR pszHeaders,
  2190. BOOL fKeepConnection
  2191. )
  2192. /*++
  2193. Purpose:
  2194. Send specified HTTP status string and any additional header strings
  2195. using new ServerSupportFunction() request HSE_SEND_HEADER_EX_INFO
  2196. Arguments:
  2197. pECB - pointer to the extension control block
  2198. pszStatus - HTTP status string (e.g. "200 OK")
  2199. pszHeaders - any additional headers, separated by CRLFs and
  2200. terminated by empty line
  2201. Returns:
  2202. --*/
  2203. {
  2204. HSE_SEND_HEADER_EX_INFO header_ex_info;
  2205. BOOL success;
  2206. // test
  2207. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "SendHttpHeaders(pECB,\r\npszStatus=%s,\r\npszHeaders=%s,\r\nfKeepConnection=%d)", pszStatus, pszHeaders, (int)fKeepConnection);
  2208. header_ex_info.pszStatus = pszStatus;
  2209. header_ex_info.pszHeader = pszHeaders;
  2210. header_ex_info.cchStatus = (DWORD)strlen( pszStatus );
  2211. header_ex_info.cchHeader = (DWORD)strlen( pszHeaders );
  2212. header_ex_info.fKeepConn = fKeepConnection;
  2213. SetLastError(0);
  2214. success = pECB->ServerSupportFunction(
  2215. pECB->ConnID,
  2216. HSE_REQ_SEND_RESPONSE_HEADER_EX,
  2217. &header_ex_info,
  2218. NULL,
  2219. NULL
  2220. );
  2221. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "Exiting SendHttpHeaders()\r\nReturn Value: %d\r\nLast Error: %08x", (int)success, GetLastError());
  2222. return success;
  2223. }
  2224. HRESULT
  2225. WriteEvent(
  2226. LPTSTR lpszSource,
  2227. DWORD dwEventType,
  2228. DWORD dwEventID,
  2229. WORD cStrings,
  2230. TCHAR **apwszStrings
  2231. )
  2232. {
  2233. HANDLE hAppLog=NULL;
  2234. BOOL bSuccess=FALSE;
  2235. WORD wElogType;
  2236. DWORD dwErr;
  2237. wElogType = (WORD) dwEventType;
  2238. if (INVALID_HANDLE_VALUE != g_hEventSource)
  2239. {
  2240. bSuccess = ReportEvent(
  2241. g_hEventSource,
  2242. wElogType,
  2243. 0,
  2244. dwEventID,
  2245. g_psidUser,
  2246. cStrings,
  2247. 0,
  2248. (const TCHAR **) apwszStrings,
  2249. NULL
  2250. );
  2251. dwErr = GetLastError();
  2252. LogEventWithString(
  2253. LOGLEVEL_TRACE,
  2254. INFO,
  2255. ISAPI_EVENT_DEBUG,
  2256. "WriteEvent() - ReportEvent()\r\n"
  2257. "bSuccess: %d\r\n"
  2258. "wELogType: %d\r\n"
  2259. "dwEventID: %08x\r\n"
  2260. "Error: %08lx\r\n"
  2261. "Event Source: %s\r\n"
  2262. "cStrings: %d\r\n"
  2263. "apwszStrings: %08x",
  2264. bSuccess,
  2265. wElogType,
  2266. dwEventID,
  2267. GetLastError(),
  2268. lpszSource,
  2269. cStrings,
  2270. (DWORD_PTR)apwszStrings
  2271. );
  2272. }
  2273. else
  2274. {
  2275. dwErr = GetLastError();
  2276. LogEventWithString(
  2277. LOGLEVEL_DEBUG,
  2278. INFO,
  2279. ISAPI_EVENT_DEBUG,
  2280. "WriteEvent() - RegisterEventSource() failed\r\n"
  2281. "hAppLog: %08x\r\n"
  2282. "Last Error: %08lx",
  2283. (DWORD_PTR)hAppLog,
  2284. dwErr
  2285. );
  2286. }
  2287. return((bSuccess) ? ERROR_SUCCESS : dwErr);
  2288. }
  2289. void
  2290. LogEvent(
  2291. IN DWORD dwLevel,
  2292. IN ISAPI_EVENT_TYPE emType,
  2293. IN DWORD dwEventID,
  2294. IN DWORD dwErrorID,
  2295. ...
  2296. )
  2297. /*++
  2298. Purpose:
  2299. Logs a specific event to the event log.
  2300. Sample Usage:
  2301. LogEvent(LOGLEVEL_ALWAYS, INFO, ISAPI_EVENT_ERROR_SEND, ISAPI_M_ERROR_SEND, szDestination);
  2302. Arguments:
  2303. emType - event message type (INFO, WRN, ERR, SUCC, AUDITS, AUDITF)
  2304. dwEventID - event id from messages.mc
  2305. ... - variable argument list for any event message parameters
  2306. Returns:
  2307. --*/
  2308. {
  2309. DWORD dwResult;
  2310. LPTSTR lpszTemp = NULL;
  2311. LPTSTR szParams;
  2312. LPTSTR* pParams = NULL;
  2313. DWORD dwParams = 0;
  2314. int i;
  2315. va_list arglist;
  2316. va_start( arglist, dwErrorID );
  2317. if (!(dwLevel & g_dwDebugMode))
  2318. {
  2319. goto done;
  2320. }
  2321. LogEventWithString(
  2322. LOGLEVEL_TRACE,
  2323. INFO,
  2324. ISAPI_EVENT_DEBUG,
  2325. "LogEvent()\r\n"
  2326. "emType: %ld\r\n"
  2327. "dwEventID: %08x",
  2328. emType,
  2329. dwEventID
  2330. );
  2331. __try {
  2332. dwResult = FormatMessage(
  2333. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
  2334. FORMAT_MESSAGE_FROM_SYSTEM,
  2335. g_hModule,
  2336. dwErrorID,
  2337. LANG_NEUTRAL,
  2338. (LPTSTR)&lpszTemp,
  2339. 0,
  2340. &arglist
  2341. );
  2342. if (dwResult != 0)
  2343. {
  2344. WriteEvent(_T("OCA_EXTENSION"), emType, dwEventID, 1, &lpszTemp);
  2345. if(lpszTemp)
  2346. {
  2347. LocalFree((HLOCAL)lpszTemp);
  2348. }
  2349. }
  2350. else
  2351. {
  2352. LogEventWithString(
  2353. LOGLEVEL_DEBUG,
  2354. INFO,
  2355. ISAPI_EVENT_DEBUG,
  2356. "LogEvent() - FormatMessage() failed\r\n"
  2357. "Last Error: %08x\r\n"
  2358. "EventID: %08x",
  2359. GetLastError(),
  2360. dwEventID
  2361. );
  2362. }
  2363. ;
  2364. }
  2365. __except(EXCEPTION_EXECUTE_HANDLER) {
  2366. // this is only for putting a break point here
  2367. SetLastError(GetLastError());
  2368. }
  2369. done:
  2370. va_end( arglist );
  2371. return;
  2372. }
  2373. void LogEventWithString(DWORD dwLevel, ISAPI_EVENT_TYPE emType, DWORD dwEventID, LPCTSTR pFormat, ...)
  2374. /*++
  2375. Purpose:
  2376. Logs a generic event with a custom string to the event log. Mostly intended
  2377. to be used for debugging purposes.
  2378. Sample Usage:
  2379. LogEventWithString(LOGLEVEL_ALWAYS, ERR, ISAPI_EVENT_ERROR, "Failed to write %s (%d)", szFilename, dwLastErr);
  2380. LogEventWithString(LOGLEVEL_DEBUG, INFO, ISAPI_EVENT_DEBUG, "Failed to write %s (%d)", szFilename, dwLastErr);
  2381. Arguments:
  2382. emType - event message type (DBG, INFO, WARN, ERROR, SUCCESS, AUDIT_SUCCESS, AUDIT_FAIL)
  2383. dwEventID - event id from messages.mc
  2384. pFormat - format string to use for variable argument parameter list
  2385. ... - variable argument list for any event message parameters
  2386. Returns:
  2387. --*/
  2388. {
  2389. TCHAR chMsg[256];
  2390. LPTSTR lpszStrings[1];
  2391. va_list pArg;
  2392. if (!(dwLevel & g_dwDebugMode))
  2393. {
  2394. goto done;
  2395. }
  2396. va_start(pArg, pFormat);
  2397. if (StringCbVPrintf(chMsg,sizeof chMsg, pFormat, pArg) != S_OK)
  2398. return;
  2399. va_end(pArg);
  2400. lpszStrings[0] = chMsg;
  2401. if (INVALID_HANDLE_VALUE != g_hEventSource)
  2402. {
  2403. /* Write to event log. */
  2404. ReportEvent(g_hEventSource, emType, 0, dwEventID, g_psidUser, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
  2405. }
  2406. done:
  2407. ;
  2408. }
  2409. /*
  2410. ///////////////////////////////////////////////////////////////////////////////////////
  2411. // Routine to Log Fatal Errors to NT Event Log
  2412. VOID LogFatalEvent(LPCTSTR pFormat, ...)
  2413. {
  2414. TCHAR chMsg[256];
  2415. LPTSTR lpszStrings[1];
  2416. va_list pArg;
  2417. va_start(pArg, pFormat);
  2418. StringCbVPrintf(chMsg,sizeof chMsg, pFormat, pArg);
  2419. va_end(pArg);
  2420. lpszStrings[0] = chMsg;
  2421. if (INVALID_HANDLE_VALUE != g_hEventSource)
  2422. {
  2423. //Write to event log.
  2424. ReportEvent(g_hEventSource,
  2425. EVENTLOG_ERROR_TYPE,
  2426. 0,
  2427. EVENT_ERROR,
  2428. NULL,
  2429. 1,
  2430. 0,
  2431. (LPCTSTR*) &lpszStrings[0],
  2432. NULL);
  2433. }
  2434. }
  2435. */
  2436. ///////////////////////////////////////////////////////////////////////////////////////
  2437. // Routine to setup NT Event logging
  2438. DWORD SetupEventLog ( BOOL fSetup )
  2439. {
  2440. TCHAR s_cszEventLogKey[] = _T("System\\CurrentControlSet\\Services\\EventLog\\Application"); // Event Log
  2441. HKEY hKey;
  2442. HKEY hSubKey;
  2443. TCHAR szEventKey[MAX_PATH];
  2444. LONG lRes = 0;
  2445. DWORD dwResult = 0;
  2446. DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
  2447. dwResult = StringCbCopy(szEventKey, sizeof szEventKey, s_cszEventLogKey);
  2448. if (dwResult !=S_OK)
  2449. {
  2450. LogEvent(LOGLEVEL_ALWAYS, ERR, ISAPI_EVENT_ERROR_SETUP_EVENT_LOG, ISAPI_M_ERROR_SETUP_EVENT_LOG, dwResult);
  2451. goto done;
  2452. }
  2453. else
  2454. {
  2455. dwResult = StringCbCat(szEventKey, sizeof szEventKey, _T("\\"));
  2456. if (dwResult != S_OK)
  2457. {
  2458. LogEvent(LOGLEVEL_ALWAYS, ERR, ISAPI_EVENT_ERROR_SETUP_EVENT_LOG, ISAPI_M_ERROR_SETUP_EVENT_LOG, dwResult);
  2459. goto done;
  2460. }
  2461. else
  2462. {
  2463. dwResult = StringCbCat(szEventKey, sizeof szEventKey, _T("OCA_EXTENSION"));
  2464. if (dwResult != S_OK)
  2465. {
  2466. LogEvent(LOGLEVEL_ALWAYS, ERR, ISAPI_EVENT_ERROR_SETUP_EVENT_LOG, ISAPI_M_ERROR_SETUP_EVENT_LOG, dwResult);
  2467. goto done;
  2468. }
  2469. }
  2470. }
  2471. lRes = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  2472. szEventKey,
  2473. 0,
  2474. NULL,
  2475. REG_OPTION_NON_VOLATILE,
  2476. KEY_ALL_ACCESS,
  2477. NULL,
  2478. &hSubKey,
  2479. &dwResult);
  2480. if (lRes != ERROR_SUCCESS)
  2481. {
  2482. goto done;
  2483. }
  2484. if( TRUE == fSetup )
  2485. {
  2486. g_hModule = GetModuleHandle(g_cszDefaultExtensionDll);
  2487. dwResult = StringCbCopy(g_szAppName,sizeof(g_szAppName), g_cszDefaultExtensionDll);
  2488. if (dwResult != S_OK)
  2489. {
  2490. LogEvent(LOGLEVEL_ALWAYS, ERR, ISAPI_EVENT_ERROR_SETUP_EVENT_LOG, ISAPI_M_ERROR_SETUP_EVENT_LOG, dwResult);
  2491. goto done;
  2492. }
  2493. GetModuleFileName(g_hModule, g_szAppName, sizeof(g_szAppName)/sizeof(g_szAppName[0]) );
  2494. RegSetValueEx(hSubKey,_T("EventMessageFile"),0,REG_EXPAND_SZ,(CONST BYTE *)g_szAppName,sizeof(g_szAppName)/sizeof(g_szAppName[0]));
  2495. RegSetValueEx(hSubKey,_T("TypesSupported"),0,REG_DWORD, (LPBYTE) &dwTypes, sizeof DWORD);
  2496. }
  2497. else
  2498. {
  2499. //RegDeleteKey(HKEY_LOCAL_MACHINE, szEventKey);
  2500. }
  2501. RegCloseKey(hSubKey);
  2502. // Get a handle to use with ReportEvent().
  2503. g_hEventSource = RegisterEventSource(NULL, _T("OCA_EXTENSION"));
  2504. goto done;
  2505. done:
  2506. return GetLastError();
  2507. }