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.

866 lines
20 KiB

  1. /*++
  2. Copyright (c) 1995-1996 Microsoft Corporation
  3. Module Name :
  4. Context.cxx
  5. Abstract:
  6. The file contains the implementation of the Context object. A context
  7. job is an object which stored in the logging request queue.
  8. Author:
  9. Terence Kwan ( terryk ) 18-Sep-1996
  10. Project:
  11. IIS Logging 3.0
  12. --*/
  13. #include "precomp.hxx"
  14. #include "comlog.hxx"
  15. #include "iiscnfg.h"
  16. //
  17. // statics
  18. //
  19. CRITICAL_SECTION COMLOG_CONTEXT::sm_listLock;
  20. LIST_ENTRY COMLOG_CONTEXT::sm_ContextListHead;
  21. CHAR g_pszResFromGetComputerName [MAX_PATH] ="";
  22. VOID
  23. COMLOG_CONTEXT::LoadPluginModules(
  24. VOID
  25. )
  26. /*++
  27. Routine Description:
  28. load all the plugin module from the metabase
  29. Arguments:
  30. None.
  31. Return Value:
  32. None
  33. --*/
  34. {
  35. DWORD cb;
  36. MB mb( (IMDCOM*) m_pvIMDCOM );
  37. PCHAR p;
  38. CLSID clsid;
  39. WCHAR buf[MAX_PATH];
  40. BUFFER szLoadOrder(1024);
  41. PCHAR pEnd;
  42. DWORD dwLogType;
  43. DWORD nPlugins = 0;
  44. PPLUGIN_NODE pluginNode;
  45. LPUNKNOWN punk;
  46. ILogPluginEx *pComponent;
  47. bool fExtended;
  48. HRESULT hr ;
  49. //
  50. // get the config information from the metabase
  51. //
  52. LockExclusive( );
  53. if ( !mb.Open(m_strMetabasePath.QueryStr()) )
  54. {
  55. DBGPRINTF((DBG_CONTEXT,"Unable to open MB path %s[err %x]\n",
  56. m_strMetabasePath.QueryStr(), GetLastError()));
  57. goto exit;
  58. }
  59. //
  60. // If logging disabled, bail out
  61. //
  62. if ( mb.GetDword( "", MD_LOG_TYPE, IIS_MD_UT_SERVER, &dwLogType))
  63. {
  64. if ( dwLogType == MD_LOG_TYPE_DISABLED )
  65. {
  66. DBGPRINTF((DBG_CONTEXT,"Logging disabled\n"));
  67. goto exit;
  68. }
  69. }
  70. //
  71. // Read the plugin order list
  72. //
  73. retry:
  74. cb = szLoadOrder.QuerySize( );
  75. if ( !mb.GetString( "", MD_LOG_PLUGIN_ORDER, IIS_MD_UT_SERVER, (PCHAR)szLoadOrder.QueryPtr( ), &cb ))
  76. {
  77. DWORD err = GetLastError();
  78. if ( err == ERROR_INSUFFICIENT_BUFFER )
  79. {
  80. DBGPRINTF((DBG_CONTEXT,"Buff Too Small[%d] need[%d]\n", szLoadOrder.QuerySize(), cb ));
  81. if ( cb > szLoadOrder.QuerySize( ) )
  82. {
  83. szLoadOrder.Resize( cb );
  84. goto retry;
  85. }
  86. }
  87. DBGPRINTF((DBG_CONTEXT,"Error getting pluginOrder[err %x]\n", err));
  88. mb.Close();
  89. goto exit;
  90. }
  91. mb.Close();
  92. //
  93. // Parse it
  94. //
  95. pEnd = (PCHAR)szLoadOrder.QueryPtr( );
  96. for ( p = pEnd; pEnd != NULL; p = pEnd + 1 )
  97. {
  98. if ( *p == '\0' )
  99. {
  100. break;
  101. }
  102. //
  103. // pEnd will point to the next entry
  104. //
  105. pEnd = strchr(p, ',');
  106. if ( pEnd != NULL )
  107. {
  108. *pEnd = '\0';
  109. }
  110. //
  111. // p points to the CLSID
  112. //
  113. DBGPRINTF((DBG_CONTEXT,"Got Logging clsid %s\n",p));
  114. if ( !TsIsNtServer() )
  115. {
  116. //
  117. // odbc not allowed
  118. //
  119. if ( _stricmp(p,ODBCLOG_CLSID) == 0 )
  120. {
  121. DBGPRINTF((DBG_CONTEXT,"ODBC logging not allowed for NTW\n"));
  122. continue;
  123. }
  124. }
  125. //
  126. // convert string to CLSID
  127. //
  128. mbstowcs( (WCHAR *)buf, p, MAX_PATH);
  129. hr = CLSIDFromString( buf, &clsid );
  130. if (FAILED(hr))
  131. {
  132. //
  133. // cannot convert string
  134. //
  135. DBGPRINTF((DBG_CONTEXT,"Cannot convert string to CLSID: %s\n",p));
  136. continue;
  137. }
  138. hr = CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)&punk );
  139. if (FAILED(hr))
  140. {
  141. //
  142. // cannot convert string
  143. //
  144. DBGPRINTF((DBG_CONTEXT,"Cannot create instance: %s\n",p));
  145. continue;
  146. }
  147. hr = punk->QueryInterface(IID_ILogPluginEx, (void **)&pComponent);
  148. if (SUCCEEDED(hr))
  149. {
  150. fExtended = true;
  151. }
  152. else
  153. {
  154. fExtended = false;
  155. //
  156. // Try getting the older interface
  157. //
  158. hr = punk->QueryInterface(IID_ILogPlugin, (void **)&pComponent);
  159. }
  160. punk->Release();
  161. if (FAILED(hr))
  162. {
  163. DBGPRINTF((DBG_CONTEXT,"Unable to get the Extended or the Standard Plugin Interface.\n"));
  164. continue;
  165. }
  166. //
  167. // Add the component
  168. //
  169. pluginNode = (PPLUGIN_NODE)LocalAlloc( 0, sizeof(PLUGIN_NODE) );
  170. if ( pluginNode == NULL )
  171. {
  172. pComponent->Release( );
  173. continue;
  174. }
  175. pluginNode->pComponent = pComponent;
  176. pluginNode->fSupportsExtendedInterface = fExtended;
  177. nPlugins++;
  178. InsertTailList(&m_pluginList, &pluginNode->ListEntry);
  179. //
  180. // Is this the default?
  181. //
  182. if ( _stricmp(p,EXTLOG_CLSID) == 0 )
  183. {
  184. m_fDefault = TRUE;
  185. DBGPRINTF((DBG_CONTEXT,"Logging Extended[%d]\n", m_fDefault));
  186. }
  187. }
  188. if ( nPlugins > 1 )
  189. {
  190. m_fDefault = FALSE;
  191. }
  192. exit:
  193. Unlock( );
  194. return;
  195. } // COMLOG_CONTEXT::LoadPlugInModules
  196. VOID
  197. COMLOG_CONTEXT::ReleasePluginModules(
  198. VOID
  199. )
  200. {
  201. PLIST_ENTRY listEntry;
  202. PPLUGIN_NODE pluginModule;
  203. LockExclusive( );
  204. m_fDefault = FALSE;
  205. while ( !IsListEmpty(&m_pluginList) ) {
  206. listEntry = RemoveHeadList( &m_pluginList );
  207. pluginModule = (PPLUGIN_NODE)CONTAINING_RECORD(
  208. listEntry,
  209. PLUGIN_NODE,
  210. ListEntry
  211. );
  212. pluginModule->pComponent->Release( );
  213. LocalFree( pluginModule );
  214. }
  215. Unlock( );
  216. return;
  217. } // COMLOG_CONTEXT::ReleasePlugInModules
  218. COMLOG_CONTEXT::COMLOG_CONTEXT(
  219. LPCSTR pszInstanceName,
  220. LPCSTR pszMetabasePath,
  221. LPVOID pvIMDCOM
  222. )
  223. : m_fDefault (FALSE),
  224. m_pvIMDCOM (pvIMDCOM)
  225. /*++
  226. Routine Description:
  227. Constructor for clapi context object
  228. Arguments:
  229. pszInstanceName - name of the instance
  230. Return Value:
  231. --*/
  232. {
  233. DWORD cbComputerNameSize = sizeof(g_pszResFromGetComputerName);
  234. MB mb( (IMDCOM*) m_pvIMDCOM );
  235. InitializeListHead( &m_pluginList );
  236. InitializeListHead( &m_PublicListEntry);
  237. m_strInstanceName.Copy(pszInstanceName);
  238. m_strMetabasePath.Copy(pszMetabasePath);
  239. if (g_pszResFromGetComputerName[0]==0)
  240. {
  241. if ( !GetComputerName( g_pszResFromGetComputerName, &cbComputerNameSize) )
  242. {
  243. strcpy(g_pszResFromGetComputerName,"<Server>");
  244. }
  245. }
  246. m_strComputerName.Copy(g_pszResFromGetComputerName);
  247. //
  248. // Add into the global list
  249. //
  250. EnterCriticalSection( &COMLOG_CONTEXT::sm_listLock );
  251. InsertTailList(
  252. &COMLOG_CONTEXT::sm_ContextListHead,
  253. &m_ContextListEntry
  254. );
  255. LeaveCriticalSection( &COMLOG_CONTEXT::sm_listLock );
  256. //
  257. // Load all the plugin modules
  258. //
  259. LoadPluginModules( );
  260. return;
  261. } // COMLOG_CONTEXT::COMLOG
  262. COMLOG_CONTEXT::~COMLOG_CONTEXT()
  263. /*++
  264. Routine Description:
  265. destructor
  266. Arguments:
  267. Return Value:
  268. --*/
  269. {
  270. PLIST_ENTRY listEntry;
  271. PInetLogPublic pPublic;
  272. EnterCriticalSection( &COMLOG_CONTEXT::sm_listLock );
  273. LockExclusive();
  274. RemoveEntryList(&m_ContextListEntry);
  275. ReleasePluginModules();
  276. for ( listEntry = m_PublicListEntry.Flink;
  277. listEntry != &m_PublicListEntry;
  278. listEntry = listEntry->Flink )
  279. {
  280. pPublic = (PInetLogPublic)CONTAINING_RECORD(
  281. listEntry,
  282. CInetLogPublic,
  283. m_ListEntry
  284. );
  285. pPublic->m_pContext = NULL;
  286. }
  287. Unlock();
  288. LeaveCriticalSection( &COMLOG_CONTEXT::sm_listLock );
  289. } // COMLOG_CONTEXT::~COMLOG()
  290. VOID
  291. COMLOG_CONTEXT::LogInformation(
  292. PINETLOG_INFORMATION pLogInfo
  293. )
  294. {
  295. PLIST_ENTRY listEntry;
  296. PPLUGIN_NODE plugin;
  297. CInetLogInformation inetLog;
  298. LockShared();
  299. if ( m_pluginList.Flink != &m_pluginList )
  300. {
  301. // logging is enabled
  302. inetLog.CanonicalizeLogRecord(
  303. pLogInfo,
  304. m_strInstanceName.QueryStr(),
  305. m_strComputerName.QueryStr(),
  306. m_fDefault
  307. );
  308. for ( listEntry = m_pluginList.Flink;
  309. listEntry != &m_pluginList;
  310. listEntry = listEntry->Flink )
  311. {
  312. plugin = (PPLUGIN_NODE)CONTAINING_RECORD(
  313. listEntry,
  314. PLUGIN_NODE,
  315. ListEntry
  316. );
  317. plugin->pComponent->LogInformation( &inetLog );
  318. }
  319. }
  320. Unlock();
  321. } // COMLOG_CONTEXT::LogInformation
  322. VOID
  323. COMLOG_CONTEXT::LogInformation(
  324. IInetLogInformation *pLogObj
  325. )
  326. {
  327. PLIST_ENTRY listEntry;
  328. PPLUGIN_NODE plugin;
  329. LockShared();
  330. if ( m_pluginList.Flink != &m_pluginList )
  331. {
  332. // logging is enabled
  333. for ( listEntry = m_pluginList.Flink;
  334. listEntry != &m_pluginList;
  335. listEntry = listEntry->Flink )
  336. {
  337. plugin = (PPLUGIN_NODE)CONTAINING_RECORD(
  338. listEntry,
  339. PLUGIN_NODE,
  340. ListEntry
  341. );
  342. plugin->pComponent->LogInformation( pLogObj );
  343. }
  344. }
  345. Unlock();
  346. } // COMLOG_CONTEXT::LogInformation
  347. VOID
  348. COMLOG_CONTEXT::LogCustomInformation(
  349. IN DWORD cCount,
  350. IN PCUSTOM_LOG_DATA pCustomLogData,
  351. IN LPSTR szHeaderSuffix
  352. )
  353. {
  354. //
  355. // This function is supported only if the extended interface was found on the plugin
  356. //
  357. PLIST_ENTRY listEntry;
  358. PPLUGIN_NODE plugin;
  359. LockShared();
  360. for ( listEntry = m_pluginList.Flink;
  361. listEntry != &m_pluginList;
  362. listEntry = listEntry->Flink )
  363. {
  364. plugin = (PPLUGIN_NODE)CONTAINING_RECORD(
  365. listEntry,
  366. PLUGIN_NODE,
  367. ListEntry
  368. );
  369. if (plugin->fSupportsExtendedInterface)
  370. {
  371. plugin->pComponent->LogCustomInformation( cCount, pCustomLogData, szHeaderSuffix);
  372. }
  373. }
  374. Unlock();
  375. } // COMLOG_CONTEXT::LogCustomInformation
  376. VOID
  377. COMLOG_CONTEXT::NotifyChange(
  378. VOID
  379. )
  380. {
  381. TerminateLog();
  382. ReleasePluginModules( );
  383. LoadPluginModules( );
  384. InitializeLog(
  385. m_strInstanceName.QueryStr(),
  386. m_strMetabasePath.QueryStr(),
  387. (CHAR*)m_pvIMDCOM
  388. );
  389. } // COMLOG_CONTEXT::NotifyChange
  390. VOID
  391. COMLOG_CONTEXT::GetConfig(
  392. IN INETLOG_CONFIGURATIONA *pConfigInfo
  393. )
  394. {
  395. //
  396. // just return the first configuration information
  397. //
  398. PLIST_ENTRY listEntry;
  399. PPLUGIN_NODE plugin;
  400. LockShared( );
  401. listEntry = m_pluginList.Flink;
  402. if (listEntry != &m_pluginList){
  403. plugin = (PPLUGIN_NODE)CONTAINING_RECORD(
  404. listEntry,
  405. PLUGIN_NODE,
  406. ListEntry
  407. );
  408. plugin->pComponent->GetConfig(
  409. sizeof(INETLOG_CONFIGURATIONA),
  410. (BYTE *)pConfigInfo);
  411. Unlock( );
  412. return;
  413. }
  414. //
  415. // No Log
  416. //
  417. Unlock( );
  418. pConfigInfo->inetLogType = INET_LOG_DISABLED;
  419. return;
  420. } // GetConfig
  421. VOID
  422. COMLOG_CONTEXT::SetConfig(
  423. IN INETLOG_CONFIGURATIONA *pConfigInfo
  424. )
  425. {
  426. //
  427. // check the log type and call the proper setconfig function
  428. //
  429. MB mb( (IMDCOM*) m_pvIMDCOM );
  430. //
  431. // NTW restrictions
  432. //
  433. if ( (pConfigInfo->inetLogType == INET_LOG_TO_SQL) &&
  434. !TsIsNtServer() ) {
  435. return;
  436. }
  437. if ( !mb.Open( m_strMetabasePath.QueryStr(),
  438. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE ))
  439. {
  440. return;
  441. }
  442. //
  443. // Release all
  444. //
  445. ReleasePluginModules( );
  446. switch (pConfigInfo->inetLogType) {
  447. case INET_LOG_TO_FILE:
  448. switch (pConfigInfo->u.logFile.ilFormat) {
  449. case INET_LOG_FORMAT_INTERNET_STD:
  450. mb.SetString("",
  451. MD_LOG_PLUGIN_ORDER,
  452. IIS_MD_UT_SERVER,
  453. ASCLOG_CLSID );
  454. break;
  455. case INET_LOG_FORMAT_NCSA:
  456. mb.SetString("",
  457. MD_LOG_PLUGIN_ORDER,
  458. IIS_MD_UT_SERVER,
  459. NCSALOG_CLSID );
  460. break;
  461. case INET_LOG_FORMAT_EXTENDED:
  462. mb.SetString("",
  463. MD_LOG_PLUGIN_ORDER,
  464. IIS_MD_UT_SERVER,
  465. EXTLOG_CLSID );
  466. mb.SetDword( "",
  467. MD_LOGEXT_FIELD_MASK,
  468. IIS_MD_UT_SERVER,
  469. pConfigInfo->u.logFile.dwFieldMask );
  470. break;
  471. default:
  472. DBGPRINTF((DBG_CONTEXT,"SetConfig: Invalid Format type %d\n",
  473. pConfigInfo->inetLogType));
  474. goto no_log;
  475. }
  476. mb.SetDword( "",
  477. MD_LOGFILE_PERIOD,
  478. IIS_MD_UT_SERVER,
  479. pConfigInfo->u.logFile.ilPeriod );
  480. if (pConfigInfo->u.logFile.ilPeriod == INET_LOG_PERIOD_NONE ) {
  481. mb.SetDword( "",
  482. MD_LOGFILE_TRUNCATE_SIZE,
  483. IIS_MD_UT_SERVER, pConfigInfo->
  484. u.logFile.cbSizeForTruncation );
  485. }
  486. mb.SetString( "",
  487. MD_LOGFILE_DIRECTORY,
  488. IIS_MD_UT_SERVER,
  489. pConfigInfo->u.logFile.rgchLogFileDirectory );
  490. mb.SetDword( "",
  491. MD_LOG_TYPE,
  492. IIS_MD_UT_SERVER,
  493. MD_LOG_TYPE_ENABLED );
  494. break;
  495. case INET_LOG_TO_SQL:
  496. mb.SetString("",
  497. MD_LOG_PLUGIN_ORDER,
  498. IIS_MD_UT_SERVER,
  499. ODBCLOG_CLSID );
  500. mb.SetString( "",
  501. MD_LOGSQL_DATA_SOURCES,
  502. IIS_MD_UT_SERVER,
  503. pConfigInfo->u.logSql.rgchDataSource );
  504. mb.SetString( "",
  505. MD_LOGSQL_TABLE_NAME,
  506. IIS_MD_UT_SERVER,
  507. pConfigInfo->u.logSql.rgchTableName );
  508. mb.SetString( "",
  509. MD_LOGSQL_USER_NAME,
  510. IIS_MD_UT_SERVER,
  511. pConfigInfo->u.logSql.rgchUserName );
  512. mb.SetString( "",
  513. MD_LOGSQL_PASSWORD,
  514. IIS_MD_UT_SERVER,
  515. pConfigInfo->u.logSql.rgchPassword,
  516. METADATA_INHERIT|METADATA_SECURE );
  517. mb.SetDword( "",
  518. MD_LOG_TYPE,
  519. IIS_MD_UT_SERVER,
  520. MD_LOG_TYPE_ENABLED );
  521. break;
  522. case INET_LOG_DISABLED:
  523. default:
  524. goto no_log;
  525. }
  526. exit:
  527. mb.Save();
  528. mb.Close();
  529. return;
  530. no_log:
  531. mb.SetString( "",
  532. MD_LOG_PLUGIN_ORDER,
  533. IIS_MD_UT_SERVER,
  534. ""
  535. );
  536. mb.SetDword( "",
  537. MD_LOG_TYPE,
  538. IIS_MD_UT_SERVER,
  539. MD_LOG_TYPE_DISABLED );
  540. goto exit;
  541. } // COMLOG_CONTEXT::SetConfig
  542. VOID
  543. COMLOG_CONTEXT::QueryExtraLogFields(
  544. PDWORD pcbSize,
  545. PCHAR pszLogFields
  546. )
  547. {
  548. PLIST_ENTRY listEntry;
  549. PPLUGIN_NODE plugin;
  550. LockShared( );
  551. listEntry = m_pluginList.Flink;
  552. if (listEntry != &m_pluginList){
  553. plugin = (PPLUGIN_NODE)CONTAINING_RECORD(
  554. listEntry,
  555. PLUGIN_NODE,
  556. ListEntry
  557. );
  558. plugin->pComponent->QueryExtraLoggingFields(
  559. pcbSize,
  560. pszLogFields
  561. );
  562. //
  563. // handle just the 1st component
  564. //
  565. Unlock( );
  566. return;
  567. }
  568. Unlock( );
  569. *pcbSize = 0;
  570. *pszLogFields = '\0';
  571. return;
  572. } // COMLOG_CONTEXT::QueryExtraLogFields
  573. VOID
  574. COMLOG_CONTEXT::InitializeLog(
  575. LPCSTR pszInstanceName,
  576. LPCSTR pszMetabasePath,
  577. LPVOID
  578. )
  579. {
  580. PLIST_ENTRY listEntry;
  581. PPLUGIN_NODE plugin;
  582. LockExclusive();
  583. for ( listEntry = m_pluginList.Flink;
  584. listEntry != &m_pluginList;
  585. listEntry = listEntry->Flink ) {
  586. plugin = (PPLUGIN_NODE)CONTAINING_RECORD(
  587. listEntry,
  588. PLUGIN_NODE,
  589. ListEntry
  590. );
  591. plugin->pComponent->InitializeLog(
  592. pszInstanceName,
  593. pszMetabasePath,
  594. (PCHAR)m_pvIMDCOM
  595. );
  596. if ( m_fDefault ) {
  597. INETLOG_CONFIGURATIONA config;
  598. m_fDefault = FALSE;
  599. if ( SUCCEEDED( plugin->pComponent->GetConfig(
  600. sizeof(config),
  601. (PBYTE)&config ) ) ) {
  602. if ( (config.u.logFile.ilFormat ==
  603. INET_LOG_FORMAT_EXTENDED)
  604. &&
  605. (config.u.logFile.dwFieldMask ==
  606. DEFAULT_EXTLOG_FIELDS) ) {
  607. m_fDefault = TRUE;
  608. }
  609. }
  610. }
  611. }
  612. Unlock();
  613. } // COMLOG_CONTEXT::InitializeLog
  614. VOID
  615. COMLOG_CONTEXT::TerminateLog(
  616. VOID
  617. )
  618. {
  619. PLIST_ENTRY listEntry;
  620. PPLUGIN_NODE plugin;
  621. LockExclusive( );
  622. for ( listEntry = m_pluginList.Flink;
  623. listEntry != &m_pluginList;
  624. listEntry = listEntry->Flink ) {
  625. plugin = (PPLUGIN_NODE)CONTAINING_RECORD(
  626. listEntry,
  627. PLUGIN_NODE,
  628. ListEntry
  629. );
  630. plugin->pComponent->TerminateLog( );
  631. }
  632. Unlock( );
  633. } // COMLOG_CONTEXT::TerminateLog