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.

729 lines
18 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name :
  4. logscript.cpp
  5. Abstract:
  6. Base implementation for ILogScripting - Automation compatible logging interface
  7. Author:
  8. Saurab Nog ( saurabn ) 01-Feb-1998
  9. Project:
  10. IIS Logging 5.0
  11. --*/
  12. #include "precomp.hxx"
  13. #include <stdio.h>
  14. #include <script.h>
  15. #include <LogScript.hxx>
  16. extern DWORD FastDwToA(CHAR* pBuf, DWORD dwV);
  17. /* ************************************************************************* */
  18. /* ************************************************************************* */
  19. CLogScript::CLogScript(
  20. VOID
  21. )
  22. :
  23. m_pInputLogFile ( NULL),
  24. m_pOutputLogFile ( NULL),
  25. m_strInputLogFileName ( ),
  26. m_pszLogLine ( NULL),
  27. m_dwLogLineSize ( 0)
  28. {
  29. INITIALIZE_CRITICAL_SECTION( &m_csLock );
  30. ReadInetLogLine.iCustomFieldsCount = 0;
  31. ResetInetLogLine(ReadInetLogLine);
  32. m_szEmpty = A2BSTR("-");
  33. }
  34. /* ************************************************************************* */
  35. /* ************************************************************************* */
  36. CLogScript::~CLogScript(
  37. VOID
  38. )
  39. {
  40. LockCS();
  41. if ( m_pInputLogFile!=NULL) {
  42. fclose(m_pInputLogFile);
  43. m_pInputLogFile = NULL;
  44. }
  45. if ( (m_pszLogLine != NULL) && (m_dwLogLineSize != 0))
  46. {
  47. delete [] m_pszLogLine;
  48. }
  49. UnlockCS();
  50. DeleteCriticalSection( &m_csLock );
  51. }
  52. /* ************************************************************************* */
  53. /* ************************************************************************* */
  54. void
  55. CLogScript::ResetInetLogLine(INET_LOGLINE& InetLogLine)
  56. {
  57. InetLogLine.pszClientHostName = NULL;
  58. InetLogLine.pszClientUserName = NULL;
  59. InetLogLine.pszServerAddress = NULL; // input ip address for connection
  60. InetLogLine.pszOperation = NULL; // eg: 'get' in FTP
  61. InetLogLine.pszTarget = NULL; // target path/machine name
  62. InetLogLine.pszParameters = NULL; // string containing parameters.
  63. InetLogLine.pszVersion = NULL; // protocol version string.
  64. InetLogLine.pszHTTPHeader = NULL; // Header Information
  65. InetLogLine.pszBytesSent = NULL; // count of bytes sent
  66. InetLogLine.pszBytesRecvd = NULL; // count of bytes recvd
  67. InetLogLine.pszTimeForProcessing = NULL; // time required for processing
  68. InetLogLine.pszWin32Status = NULL; // Win32 error code. 0 for success
  69. InetLogLine.pszProtocolStatus = NULL; // status: whatever service wants.
  70. InetLogLine.pszPort = NULL;
  71. InetLogLine.pszSiteName = NULL; // Site name (not put in https log)
  72. InetLogLine.pszComputerName = NULL; // netbios name of Server
  73. InetLogLine.DateTime = 0; // Date & Time
  74. InetLogLine.pszUserAgent = NULL; // User Agent - Browser type
  75. InetLogLine.pszCookie = NULL;
  76. InetLogLine.pszReferer = NULL; // Referring URL.
  77. for ( int i = 0; i < InetLogLine.iCustomFieldsCount-1; i++)
  78. {
  79. (InetLogLine.CustomFields[i]).pchData = NULL;
  80. }
  81. }
  82. /* ************************************************************************* */
  83. /* ************************************************************************* */
  84. //
  85. // ILogScripting Interface
  86. //
  87. /* ************************************************************************* */
  88. /* ************************************************************************* */
  89. STDMETHODIMP
  90. CLogScript::OpenLogFile(
  91. BSTR szLogFileName,
  92. IOMode Mode,
  93. BSTR,
  94. long,
  95. BSTR
  96. )
  97. {
  98. USES_CONVERSION;
  99. LockCS();
  100. if (ForReading == Mode)
  101. {
  102. if (m_pInputLogFile != NULL)
  103. {
  104. fclose(m_pInputLogFile);
  105. m_pInputLogFile = NULL;
  106. }
  107. m_strInputLogFileName.Copy(W2A(szLogFileName));
  108. if (m_pszLogLine == NULL)
  109. {
  110. m_dwLogLineSize = MAX_LOG_RECORD_LEN+1;
  111. m_pszLogLine = new CHAR[m_dwLogLineSize];
  112. if (m_pszLogLine == NULL)
  113. m_dwLogLineSize = 0;
  114. }
  115. }
  116. else
  117. {
  118. if (m_pOutputLogFile != NULL)
  119. {
  120. fclose(m_pOutputLogFile);
  121. m_pOutputLogFile = NULL;
  122. }
  123. m_strOutputLogFileName.Copy(W2A(szLogFileName));
  124. }
  125. UnlockCS();
  126. SysFreeString(szLogFileName);
  127. return(S_OK);
  128. } // SetInputLogFile
  129. /* ************************************************************************* */
  130. /* ************************************************************************* */
  131. STDMETHODIMP
  132. CLogScript::CloseLogFiles(IOMode Mode)
  133. {
  134. LockCS();
  135. if( ((ForReading == Mode) || (AllOpenFiles == Mode)) &&
  136. (m_pInputLogFile != NULL)
  137. )
  138. {
  139. fclose(m_pInputLogFile);
  140. m_pInputLogFile = NULL;
  141. }
  142. if( ((ForWriting == Mode) || (AllOpenFiles == Mode)) &&
  143. (m_pOutputLogFile != NULL)
  144. )
  145. {
  146. fclose(m_pOutputLogFile);
  147. m_pOutputLogFile = NULL;
  148. }
  149. UnlockCS();
  150. return S_OK;
  151. }
  152. /* ************************************************************************* */
  153. /* ************************************************************************* */
  154. STDMETHODIMP
  155. CLogScript::ReadFilter( DATE, DATE)
  156. {
  157. return S_OK;
  158. }
  159. /* ************************************************************************* */
  160. /* ************************************************************************* */
  161. STDMETHODIMP
  162. CLogScript::ReadLogRecord( VOID )
  163. {
  164. HRESULT hr = S_OK;
  165. LockCS();
  166. if (m_pInputLogFile == NULL)
  167. {
  168. m_pInputLogFile = fopen(m_strInputLogFileName.QueryStr(), "r");
  169. if (m_pInputLogFile == NULL)
  170. {
  171. return E_FAIL;
  172. }
  173. }
  174. ResetInetLogLine(ReadInetLogLine);
  175. //
  176. // Call the plugin to fill in the INET_LOGLINE structure
  177. //
  178. hr = ReadFileLogRecord(m_pInputLogFile, &ReadInetLogLine, m_pszLogLine, m_dwLogLineSize);
  179. if (SUCCEEDED(hr))
  180. {
  181. hr = S_OK;
  182. }
  183. UnlockCS();
  184. return(hr);
  185. } // ReadLogRecord
  186. /* ************************************************************************* */
  187. /* ************************************************************************* */
  188. STDMETHODIMP
  189. CLogScript::AtEndOfLog(VARIANT_BOOL *)
  190. {
  191. return S_OK;
  192. }
  193. /* ************************************************************************* */
  194. /* ************************************************************************* */
  195. STDMETHODIMP
  196. CLogScript::WriteLogRecord(ILogScripting * pILogScripting)
  197. {
  198. HRESULT hr = S_OK;
  199. bool fWriteHeader = false;
  200. LockCS();
  201. if (m_pOutputLogFile == NULL)
  202. {
  203. m_pOutputLogFile = fopen(m_strOutputLogFileName.QueryStr(), "w+");
  204. if (m_pOutputLogFile == NULL)
  205. {
  206. return E_FAIL;
  207. }
  208. fWriteHeader = true;
  209. }
  210. //
  211. // Call the plugin to write the INET_LOGLINE structure to file
  212. //
  213. hr = WriteFileLogRecord(m_pOutputLogFile, pILogScripting, fWriteHeader);
  214. if (SUCCEEDED(hr))
  215. {
  216. hr = S_OK;
  217. }
  218. UnlockCS();
  219. return(hr);
  220. }
  221. /* ************************************************************************* */
  222. /* ************************************************************************* */
  223. STDMETHODIMP
  224. CLogScript::get_DateTime( VARIANT * pvarDateTime)
  225. {
  226. LockCS();
  227. pvarDateTime->vt = VT_DATE;
  228. pvarDateTime->date = ReadInetLogLine.DateTime;
  229. UnlockCS();
  230. return S_OK;
  231. }
  232. /* ************************************************************************* */
  233. /* ************************************************************************* */
  234. STDMETHODIMP
  235. CLogScript::get_ServiceName(VARIANT * pvarServiceName)
  236. {
  237. LockCS();
  238. SetVariantToBstr(pvarServiceName, ReadInetLogLine.pszSiteName) ;
  239. UnlockCS();
  240. return S_OK;
  241. }
  242. /* ************************************************************************* */
  243. /* ************************************************************************* */
  244. STDMETHODIMP
  245. CLogScript::get_ServerName(VARIANT * pvarServerName)
  246. {
  247. LockCS();
  248. SetVariantToBstr(pvarServerName, ReadInetLogLine.pszComputerName);
  249. UnlockCS();
  250. return S_OK;
  251. }
  252. /* ************************************************************************* */
  253. /* ************************************************************************* */
  254. STDMETHODIMP
  255. CLogScript::get_ClientIP(VARIANT * pvarClientIP)
  256. {
  257. LockCS();
  258. SetVariantToBstr(pvarClientIP, ReadInetLogLine.pszClientHostName);
  259. UnlockCS();
  260. return S_OK;
  261. }
  262. /* ************************************************************************* */
  263. /* ************************************************************************* */
  264. STDMETHODIMP
  265. CLogScript::get_UserName(VARIANT * pvarUserName)
  266. {
  267. LockCS();
  268. SetVariantToBstr(pvarUserName, ReadInetLogLine.pszClientUserName);
  269. UnlockCS();
  270. return S_OK;
  271. }
  272. /* ************************************************************************* */
  273. /* ************************************************************************* */
  274. STDMETHODIMP
  275. CLogScript::get_ServerIP(VARIANT * pvarServerIP)
  276. {
  277. LockCS();
  278. SetVariantToBstr(pvarServerIP, ReadInetLogLine.pszServerAddress);
  279. UnlockCS();
  280. return S_OK;
  281. }
  282. /* ************************************************************************* */
  283. /* ************************************************************************* */
  284. STDMETHODIMP
  285. CLogScript::get_Method(VARIANT * pvarMethod)
  286. {
  287. LockCS();
  288. SetVariantToBstr(pvarMethod, ReadInetLogLine.pszOperation);
  289. UnlockCS();
  290. return S_OK;
  291. }
  292. /* ************************************************************************* */
  293. /* ************************************************************************* */
  294. STDMETHODIMP
  295. CLogScript::get_URIStem(VARIANT * pvarURIStem)
  296. {
  297. LockCS();
  298. SetVariantToBstr(pvarURIStem, ReadInetLogLine.pszTarget);
  299. UnlockCS();
  300. return S_OK;
  301. }
  302. /* ************************************************************************* */
  303. /* ************************************************************************* */
  304. STDMETHODIMP
  305. CLogScript::get_URIQuery(VARIANT * pvarURIQuery)
  306. {
  307. LockCS();
  308. SetVariantToBstr( pvarURIQuery, ReadInetLogLine.pszParameters);
  309. UnlockCS();
  310. return S_OK;
  311. }
  312. /* ************************************************************************* */
  313. /* ************************************************************************* */
  314. STDMETHODIMP
  315. CLogScript::get_TimeTaken(VARIANT * pvarTimeTaken)
  316. {
  317. LockCS();
  318. SetVariantToLong(pvarTimeTaken, ReadInetLogLine.pszTimeForProcessing);
  319. UnlockCS();
  320. return S_OK;
  321. }
  322. /* ************************************************************************* */
  323. /* ************************************************************************* */
  324. STDMETHODIMP
  325. CLogScript::get_BytesSent( VARIANT * pvarBytesSent )
  326. {
  327. LockCS();
  328. SetVariantToLong(pvarBytesSent, ReadInetLogLine.pszBytesSent);
  329. UnlockCS();
  330. return S_OK;
  331. }
  332. /* ************************************************************************* */
  333. /* ************************************************************************* */
  334. STDMETHODIMP
  335. CLogScript::get_BytesReceived(VARIANT * pvarBytesReceived)
  336. {
  337. LockCS();
  338. SetVariantToLong(pvarBytesReceived, ReadInetLogLine.pszBytesRecvd);
  339. UnlockCS();
  340. return S_OK;
  341. }
  342. /* ************************************************************************* */
  343. /* ************************************************************************* */
  344. STDMETHODIMP
  345. CLogScript::get_Win32Status( VARIANT * pvarWin32Status )
  346. {
  347. LockCS();
  348. SetVariantToLong(pvarWin32Status, ReadInetLogLine.pszWin32Status);
  349. UnlockCS();
  350. return S_OK;
  351. }
  352. /* ************************************************************************* */
  353. /* ************************************************************************* */
  354. STDMETHODIMP
  355. CLogScript::get_ProtocolStatus( VARIANT * pvarProtocolStatus )
  356. {
  357. LockCS();
  358. SetVariantToLong(pvarProtocolStatus, ReadInetLogLine.pszProtocolStatus);
  359. UnlockCS();
  360. return S_OK;
  361. }
  362. /* ************************************************************************* */
  363. /* ************************************************************************* */
  364. STDMETHODIMP
  365. CLogScript::get_ServerPort(VARIANT * pvarServerPort)
  366. {
  367. LockCS();
  368. SetVariantToLong(pvarServerPort, ReadInetLogLine.pszPort);
  369. UnlockCS();
  370. return S_OK;
  371. }
  372. /* ************************************************************************* */
  373. /* ************************************************************************* */
  374. STDMETHODIMP
  375. CLogScript::get_ProtocolVersion(VARIANT * pvarProtocolVersion)
  376. {
  377. LockCS();
  378. SetVariantToBstr(pvarProtocolVersion, ReadInetLogLine.pszVersion);
  379. UnlockCS();
  380. return S_OK;
  381. }
  382. /* ************************************************************************* */
  383. /* ************************************************************************* */
  384. STDMETHODIMP
  385. CLogScript::get_UserAgent(VARIANT * pvarUserAgent)
  386. {
  387. LockCS();
  388. SetVariantToBstr(pvarUserAgent, ReadInetLogLine.pszUserAgent);
  389. UnlockCS();
  390. return S_OK;
  391. }
  392. /* ************************************************************************* */
  393. /* ************************************************************************* */
  394. STDMETHODIMP
  395. CLogScript::get_Cookie(VARIANT * pvarCookie)
  396. {
  397. LockCS();
  398. SetVariantToBstr(pvarCookie, ReadInetLogLine.pszCookie);
  399. UnlockCS();
  400. return S_OK;
  401. }
  402. /* ************************************************************************* */
  403. /* ************************************************************************* */
  404. STDMETHODIMP
  405. CLogScript::get_Referer(VARIANT * pvarReferer)
  406. {
  407. LockCS();
  408. SetVariantToBstr(pvarReferer, ReadInetLogLine.pszReferer);
  409. UnlockCS();
  410. return S_OK;
  411. }
  412. /* ************************************************************************* */
  413. /* ************************************************************************* */
  414. STDMETHODIMP
  415. CLogScript::get_CustomFields(VARIANT * pvarCustomFieldsArray)
  416. {
  417. USES_CONVERSION;
  418. HRESULT hr = S_OK;
  419. int cItems;
  420. cItems = ReadInetLogLine.iCustomFieldsCount;
  421. // we will leave that value in case of error
  422. pvarCustomFieldsArray->vt = VT_NULL;
  423. if ( 0 < cItems)
  424. {
  425. // Create 2D SafeArray & stuff with header & string pairs
  426. SAFEARRAYBOUND rgsabound[2];
  427. rgsabound[0].lLbound = rgsabound[1].lLbound = 0;
  428. rgsabound[0].cElements = ReadInetLogLine.iCustomFieldsCount;
  429. rgsabound[1].cElements = 2;
  430. SAFEARRAY * psaCustom = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
  431. if ( NULL != psaCustom)
  432. {
  433. long i;
  434. long ix[2];
  435. VARIANT v;
  436. ix[1]=0;
  437. for ( i = 0; i < cItems; i++)
  438. {
  439. VariantInit(&v);
  440. v.vt = VT_BSTR;
  441. v.bstrVal = A2BSTR(ReadInetLogLine.CustomFields[i].szHeader);
  442. ix[0]=i;
  443. hr = SafeArrayPutElement( psaCustom, ix, &v );
  444. VariantClear(&v);
  445. if (FAILED (hr))
  446. {
  447. goto exit_point;
  448. }
  449. }
  450. ix[1]=1;
  451. for ( i = 0; i < cItems; i++)
  452. {
  453. VariantInit(&v);
  454. v.vt = VT_BSTR;
  455. v.bstrVal = A2BSTR(ReadInetLogLine.CustomFields[i].pchData);
  456. ix[0]=i;
  457. hr = SafeArrayPutElement( psaCustom, ix, &v );
  458. VariantClear(&v);
  459. if (FAILED (hr))
  460. {
  461. goto exit_point;
  462. }
  463. }
  464. }
  465. if (NULL != pvarCustomFieldsArray)
  466. {
  467. pvarCustomFieldsArray->vt = VT_ARRAY|VT_VARIANT;
  468. pvarCustomFieldsArray->parray = psaCustom;
  469. }
  470. }
  471. exit_point:
  472. return hr;
  473. }
  474. /* ************************************************************************* */
  475. /* ************************************************************************* */
  476. VOID
  477. CLogScript::SetVariantToBstr (VARIANT * pVar, LPSTR pCh)
  478. {
  479. USES_CONVERSION;
  480. if ( NULL == pCh)
  481. {
  482. pVar->vt = VT_NULL;
  483. }
  484. else if ( 0 == strcmp( pCh, "-"))
  485. {
  486. pVar->vt = VT_EMPTY;
  487. }
  488. else
  489. {
  490. pVar->vt = VT_BSTR;
  491. pVar->bstrVal= A2BSTR(pCh);
  492. }
  493. }
  494. /* ************************************************************************* */
  495. /* ************************************************************************* */
  496. VOID
  497. CLogScript::SetVariantToLong (VARIANT * pVar, LPSTR pCh)
  498. {
  499. if ( NULL == pCh)
  500. {
  501. pVar->vt = VT_NULL;
  502. }
  503. else if ( 0 == strcmp( pCh, "-"))
  504. {
  505. pVar->vt = VT_EMPTY;
  506. }
  507. else
  508. {
  509. pVar->vt = VT_I4;
  510. pVar->lVal = atol(pCh);
  511. }
  512. }
  513. /* ************************************************************************* */
  514. /* ************************************************************************* */
  515. BSTR
  516. CLogScript::GetBstrFromVariant (VARIANT * pVar)
  517. {
  518. if ((VT_NULL == pVar->vt) ||
  519. (VT_EMPTY == pVar->vt)
  520. )
  521. {
  522. return m_szEmpty;
  523. }
  524. else
  525. {
  526. return pVar->bstrVal;
  527. }
  528. }
  529. /* ************************************************************************* */
  530. /* ************************************************************************* */
  531. DWORD
  532. CLogScript::GetLongFromVariant (VARIANT * pVar, CHAR * pBuffer)
  533. {
  534. if ((VT_NULL == pVar->vt) ||
  535. (VT_EMPTY == pVar->vt)
  536. )
  537. {
  538. pBuffer[0] = '-';
  539. pBuffer[1] = '\0';
  540. return 1;
  541. }
  542. else
  543. {
  544. return FastDwToA(pBuffer, pVar->lVal);
  545. }
  546. }
  547. /* ************************************************************************* */
  548. /* ************************************************************************* */