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.

545 lines
10 KiB

  1. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. w3spoof.cpp
  5. Abstract:
  6. Implements the W3Spoof application object and the following interfaces:
  7. IConfig
  8. IConnectionPointContainer
  9. IConnectionPoint (via contained CW3SpoofEventsCP object)
  10. Author:
  11. Paul M Midgen (pmidge) 07-June-2000
  12. Revision History:
  13. 07-June-2000 pmidge
  14. Created
  15. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  16. #include "common.h"
  17. LPCWSTR g_wszPoolSize = L"MaxPoolSize";
  18. LPCWSTR g_wszActiveThreads = L"MaxActiveThreads";
  19. LPCWSTR g_wszServerPort = L"ServerPort";
  20. //-----------------------------------------------------------------------------
  21. // CW3Spoof methods
  22. //-----------------------------------------------------------------------------
  23. CW3Spoof::CW3Spoof():
  24. m_cRefs(0),
  25. m_cExtRefs(0),
  26. m_evtServerUnload(INVALID_HANDLE_VALUE),
  27. m_prt(NULL),
  28. m_ptl(NULL),
  29. m_clientmap(NULL),
  30. m_sessionmap(NULL),
  31. m_dwPoolSize(0),
  32. m_dwMaxActiveThreads(0),
  33. m_usServerPort(8080),
  34. m_arThreads(NULL),
  35. m_sListen(INVALID_SOCKET),
  36. m_hIOCP(NULL),
  37. m_AcceptQueueStatus(1),
  38. m_MaxQueuedAccepts(10),
  39. m_PendingAccepts(10)
  40. {
  41. DEBUG_TRACE(W3SOBJ, ("CW3Spoof created: %#x", this));
  42. _SetState(ST_OPENING);
  43. }
  44. CW3Spoof::~CW3Spoof()
  45. {
  46. DEBUG_TRACE(W3SOBJ, ("CW3Spoof deleted: %#x", this));
  47. }
  48. HRESULT
  49. CW3Spoof::Create(IW3Spoof** ppw3s)
  50. {
  51. DEBUG_ENTER((
  52. DBG_W3SOBJ,
  53. rt_hresult,
  54. "CW3Spoof::Create",
  55. "ppw3s=%#x",
  56. ppw3s
  57. ));
  58. HRESULT hr = E_FAIL;
  59. CW3Spoof* pw3s = NULL;
  60. if( pw3s = new CW3Spoof )
  61. {
  62. if( pw3s->_Initialize() != ERROR_SUCCESS )
  63. {
  64. DEBUG_TRACE(W3SOBJ, ("object initialization failed"));
  65. delete pw3s;
  66. goto quit;
  67. }
  68. }
  69. else
  70. {
  71. DEBUG_TRACE(W3SOBJ, ("failed to allocate object: %s", GetLastError()));
  72. *ppw3s = NULL;
  73. goto quit;
  74. }
  75. hr = pw3s->QueryInterface(IID_IW3Spoof, (void**) ppw3s);
  76. if( FAILED(hr) )
  77. {
  78. *ppw3s = NULL;
  79. delete pw3s;
  80. }
  81. quit:
  82. DEBUG_LEAVE(hr);
  83. return hr;
  84. }
  85. DWORD
  86. CW3Spoof::_Initialize(void)
  87. {
  88. DEBUG_ENTER((
  89. DBG_W3SOBJ,
  90. rt_dword,
  91. "CW3Spoof::_Initialize",
  92. "this=%#x",
  93. this
  94. ));
  95. DWORD dwRet = ERROR_SUCCESS;
  96. HRESULT hr = S_OK;
  97. WCHAR* buf = NULL;
  98. CLSID clsid = {0};
  99. SYSTEM_INFO si = {0};
  100. IActiveScriptParse* parse = NULL;
  101. if( m_state != ST_OPENING )
  102. {
  103. dwRet = ERROR_INVALID_STATE;
  104. goto quit;
  105. }
  106. GetSystemInfo(&si);
  107. m_dwPoolSize = si.dwNumberOfProcessors;
  108. m_dwMaxActiveThreads = si.dwNumberOfProcessors;
  109. _LoadRegDefaults();
  110. m_CP.SetSite(dynamic_cast<IW3Spoof*>(this));
  111. if( !_InitializeThreads() )
  112. {
  113. dwRet = ERROR_FAILURE;
  114. DEBUG_TRACE(W3SOBJ, ("error creating worker threads"));
  115. goto quit;
  116. }
  117. m_clientmap = new STRINGMAP;
  118. if( m_clientmap )
  119. {
  120. m_clientmap->SetClearFunction(BSTRKiller);
  121. }
  122. else
  123. {
  124. dwRet = ERROR_OUTOFMEMORY;
  125. goto quit;
  126. }
  127. m_sessionmap = new STRINGMAP;
  128. buf = new WCHAR[MAX_PATH];
  129. if( !(m_sessionmap && buf) )
  130. {
  131. dwRet = ERROR_OUTOFMEMORY;
  132. goto quit;
  133. }
  134. GetModuleFileName(NULL, buf, MAX_PATH);
  135. hr = LoadTypeLib(buf, &m_ptl);
  136. if( FAILED(hr) )
  137. {
  138. dwRet = ERROR_FAILURE;
  139. DEBUG_TRACE(W3SOBJ, ("failed to load type library - %s", MapHResultToString(hr)));
  140. }
  141. if( FAILED(RUNTIME::Create(&m_prt)) )
  142. {
  143. dwRet = ERROR_FAILURE;
  144. DEBUG_TRACE(W3SOBJ, ("failed to create runtime"));
  145. goto quit;
  146. }
  147. if( GetJScriptCLSID(&clsid) )
  148. {
  149. hr = CoCreateInstance(
  150. clsid,
  151. NULL,
  152. CLSCTX_ALL,
  153. IID_IActiveScript,
  154. (void**) &m_pas
  155. );
  156. if( FAILED(hr) )
  157. {
  158. dwRet = ERROR_FAILURE;
  159. DEBUG_TRACE(W3SOBJ, ("error cocreating script engine - %s", MapHResultToString(hr)));
  160. }
  161. else
  162. {
  163. hr = m_pas->QueryInterface(IID_IActiveScriptParse, (void**) &parse);
  164. if( FAILED(hr) )
  165. goto quit;
  166. hr = parse->InitNew();
  167. }
  168. }
  169. else
  170. {
  171. DEBUG_TRACE(W3SOBJ, ("ERROR! Couldn't find the JScript CLSID."));
  172. dwRet = ERROR_FAILURE;
  173. goto quit;
  174. }
  175. m_evtServerUnload = CreateEvent(NULL, TRUE, FALSE, NULL);
  176. quit:
  177. _SetState(
  178. (dwRet == ERROR_SUCCESS) ? ST_OPEN : ST_ERROR
  179. );
  180. SAFEDELETEBUF(buf);
  181. SAFERELEASE(parse);
  182. DEBUG_LEAVE(dwRet);
  183. return dwRet;
  184. }
  185. void
  186. CW3Spoof::_LoadRegDefaults(void)
  187. {
  188. LPDWORD pdw = NULL;
  189. if( GetRegValue(g_wszPoolSize, REG_DWORD, (void**) &pdw) )
  190. {
  191. m_dwPoolSize = *pdw;
  192. DEBUG_TRACE(W3SOBJ, ("pool size: %d", m_dwPoolSize));
  193. delete pdw;
  194. }
  195. if( GetRegValue(g_wszActiveThreads, REG_DWORD, (void**) &pdw) )
  196. {
  197. m_dwMaxActiveThreads = *pdw;
  198. DEBUG_TRACE(W3SOBJ, ("max active threads: %d", m_dwMaxActiveThreads));
  199. delete pdw;
  200. }
  201. if( GetRegValue(g_wszServerPort, REG_DWORD, (void**) &pdw) )
  202. {
  203. m_usServerPort = (USHORT) *pdw;
  204. DEBUG_TRACE(W3SOBJ, ("server port: %d", m_usServerPort));
  205. delete pdw;
  206. }
  207. }
  208. void
  209. CW3Spoof::_SetState(STATE st)
  210. {
  211. DEBUG_TRACE(W3SOBJ, ("w3sobj state: %s", MapStateToString(st)));
  212. m_state = st;
  213. }
  214. //-----------------------------------------------------------------------------
  215. // IConfig
  216. //-----------------------------------------------------------------------------
  217. HRESULT
  218. __stdcall
  219. CW3Spoof::SetOption(DWORD dwOption, LPDWORD lpdwValue)
  220. {
  221. return E_NOTIMPL;
  222. }
  223. HRESULT
  224. __stdcall
  225. CW3Spoof::GetOption(DWORD dwOption, LPDWORD lpdwValue)
  226. {
  227. return E_NOTIMPL;
  228. }
  229. //-----------------------------------------------------------------------------
  230. // IConnectionPointContainer
  231. //-----------------------------------------------------------------------------
  232. HRESULT
  233. __stdcall
  234. CW3Spoof::EnumConnectionPoints(IEnumConnectionPoints** ppEnum)
  235. {
  236. return E_NOTIMPL;
  237. }
  238. HRESULT
  239. __stdcall
  240. CW3Spoof::FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP)
  241. {
  242. DEBUG_ENTER((
  243. DBG_W3SOBJ,
  244. rt_hresult,
  245. "CW3Spoof::FindConnectionPoint",
  246. "this=%#x; riid=%s; ppCP=%#x",
  247. this,
  248. MapIIDToString(riid),
  249. ppCP
  250. ));
  251. HRESULT hr = S_OK;
  252. if( !ppCP )
  253. {
  254. hr = E_POINTER;
  255. goto quit;
  256. }
  257. if( IsEqualIID(riid, IID_IW3SpoofEvents) )
  258. {
  259. hr = m_CP.QueryInterface(IID_IConnectionPoint, (void**) ppCP);
  260. }
  261. else
  262. {
  263. *ppCP = NULL;
  264. hr = CONNECT_E_NOCONNECTION;
  265. }
  266. quit:
  267. DEBUG_LEAVE(hr);
  268. return hr;
  269. }
  270. //-----------------------------------------------------------------------------
  271. // IConnectionPoint
  272. //-----------------------------------------------------------------------------
  273. HRESULT
  274. __stdcall
  275. CW3Spoof::CW3SpoofEventsCP::QueryInterface(REFIID riid, void** ppv)
  276. {
  277. DEBUG_ENTER((
  278. DBG_REFCOUNT,
  279. rt_hresult,
  280. "CW3SpoofEventsCP::QueryInterface",
  281. "this=%#x; riid=%s; ppv=%#x",
  282. this,
  283. MapIIDToString(riid),
  284. ppv
  285. ));
  286. HRESULT hr = S_OK;
  287. if( IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IConnectionPoint) )
  288. {
  289. *ppv = static_cast<IConnectionPoint*>(this);
  290. }
  291. else
  292. {
  293. *ppv = NULL;
  294. hr = E_NOINTERFACE;
  295. }
  296. if( SUCCEEDED(hr) )
  297. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  298. DEBUG_LEAVE(hr);
  299. return hr;
  300. }
  301. ULONG
  302. __stdcall
  303. CW3Spoof::CW3SpoofEventsCP::AddRef(void)
  304. {
  305. InterlockedIncrement(&m_cRefs);
  306. DEBUG_ADDREF("CW3SpoofEventsCP", m_cRefs);
  307. return m_cRefs;
  308. }
  309. ULONG
  310. __stdcall
  311. CW3Spoof::CW3SpoofEventsCP::Release(void)
  312. {
  313. InterlockedDecrement(&m_cRefs);
  314. DEBUG_RELEASE("CW3SpoofEventsCP", m_cRefs);
  315. return m_cRefs;
  316. }
  317. HRESULT
  318. __stdcall
  319. CW3Spoof::CW3SpoofEventsCP::GetConnectionInterface(IID* pIID)
  320. {
  321. DEBUG_ENTER((
  322. DBG_W3SOBJ,
  323. rt_hresult,
  324. "CW3SpoofEventsCP::GetConnectionInterface",
  325. "this=%#x; pIID=%s",
  326. this,
  327. MapIIDToString((const IID&)pIID)
  328. ));
  329. HRESULT hr = S_OK;
  330. if( !pIID )
  331. {
  332. hr = E_POINTER;
  333. }
  334. else
  335. {
  336. *pIID = IID_IW3SpoofEvents;
  337. }
  338. DEBUG_LEAVE(hr);
  339. return hr;
  340. }
  341. HRESULT
  342. __stdcall
  343. CW3Spoof::CW3SpoofEventsCP::GetConnectionPointContainer(IConnectionPointContainer** ppCPC)
  344. {
  345. DEBUG_ENTER((
  346. DBG_W3SOBJ,
  347. rt_hresult,
  348. "CW3SpoofEventsCP::GetConnectionPointContainer",
  349. "this=%#x; ppCPC=%#x",
  350. this,
  351. ppCPC
  352. ));
  353. HRESULT hr = S_OK;
  354. if( !ppCPC )
  355. {
  356. hr = E_POINTER;
  357. }
  358. else
  359. {
  360. hr = m_pSite->QueryInterface(IID_IConnectionPointContainer, (void**) ppCPC);
  361. }
  362. DEBUG_LEAVE(hr);
  363. return hr;
  364. }
  365. HRESULT
  366. __stdcall
  367. CW3Spoof::CW3SpoofEventsCP::Advise(IUnknown* punkSink, LPDWORD pdwCookie)
  368. {
  369. DEBUG_ENTER((
  370. DBG_W3SOBJ,
  371. rt_hresult,
  372. "CW3SpoofEventsCP::Advise",
  373. "this=%#x; punkSink=%#x; pdwCookie=%#x",
  374. this,
  375. punkSink,
  376. pdwCookie
  377. ));
  378. HRESULT hr = S_OK;
  379. if( !punkSink || !pdwCookie )
  380. {
  381. hr = E_POINTER;
  382. goto quit;
  383. }
  384. if( m_cConnections != 0 )
  385. {
  386. hr = CONNECT_E_ADVISELIMIT;
  387. goto quit;
  388. }
  389. hr = punkSink->QueryInterface(IID_IW3SpoofEvents, (void**) &m_pSink);
  390. if( SUCCEEDED(hr) )
  391. {
  392. *pdwCookie = m_dwCookie = 1L;
  393. ++m_cConnections;
  394. }
  395. else
  396. {
  397. *pdwCookie = 0L;
  398. m_pSink = NULL;
  399. hr = CONNECT_E_CANNOTCONNECT;
  400. }
  401. quit:
  402. DEBUG_LEAVE(hr);
  403. return hr;
  404. }
  405. HRESULT
  406. __stdcall
  407. CW3Spoof::CW3SpoofEventsCP::Unadvise(DWORD dwCookie)
  408. {
  409. DEBUG_ENTER((
  410. DBG_W3SOBJ,
  411. rt_hresult,
  412. "CW3SpoofEventsCP::Unadvise",
  413. "this=%#x; dwCookie=%d",
  414. this,
  415. dwCookie
  416. ));
  417. HRESULT hr = S_OK;
  418. if( dwCookie != 1L )
  419. {
  420. hr = CONNECT_E_NOCONNECTION;
  421. }
  422. else
  423. {
  424. m_pSink->Release();
  425. m_pSink = NULL;
  426. m_dwCookie = 0L;
  427. --m_cConnections;
  428. }
  429. DEBUG_LEAVE(hr);
  430. return hr;
  431. }
  432. HRESULT
  433. __stdcall
  434. CW3Spoof::CW3SpoofEventsCP::EnumConnections(IEnumConnections** ppEnum)
  435. {
  436. return E_NOTIMPL;
  437. }