Source code of Windows XP (NT5)
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.

555 lines
14 KiB

  1. //****************************************************************************
  2. //
  3. // Module: ULS.DLL
  4. // File: cserver.cpp
  5. // Content: This file contains the ULS server object.
  6. // History:
  7. // Wed 17-Apr-1996 11:13:54 -by- Viroon Touranachun [viroont]
  8. //
  9. // Copyright (c) Microsoft Corporation 1996-1997
  10. //
  11. //****************************************************************************
  12. #include "ulsp.h"
  13. #include "culs.h"
  14. #include "localusr.h"
  15. #include "attribs.h"
  16. #include "localprt.h"
  17. #include "callback.h"
  18. //****************************************************************************
  19. // ILS_STATE
  20. // CIlsUser::GetULSState(VOID)
  21. //
  22. // History:
  23. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  24. // Created.
  25. //****************************************************************************
  26. ILS_STATE CIlsUser::
  27. GetULSState ( VOID )
  28. {
  29. ILS_STATE uULSState;
  30. switch(m_uState)
  31. {
  32. case ULSSVR_INVALID:
  33. case ULSSVR_INIT:
  34. uULSState = ILS_UNREGISTERED;
  35. break;
  36. case ULSSVR_REG_USER:
  37. case ULSSVR_REG_PROT:
  38. uULSState = ILS_REGISTERING;
  39. break;
  40. case ULSSVR_CONNECT:
  41. uULSState = ILS_REGISTERED;
  42. break;
  43. case ULSSVR_UNREG_PROT:
  44. case ULSSVR_UNREG_USER:
  45. uULSState = ILS_UNREGISTERING;
  46. break;
  47. case ULSSVR_RELOGON:
  48. uULSState = ILS_REGISTERED_BUT_INVALID;
  49. break;
  50. case ULSSVR_NETWORK_DOWN:
  51. uULSState = ILS_NETWORK_DOWN;
  52. break;
  53. default:
  54. ASSERT(0);
  55. uULSState = ILS_UNREGISTERED;
  56. break;
  57. };
  58. return uULSState;
  59. }
  60. //****************************************************************************
  61. // void
  62. // CIlsUser::NotifyULSRegister(HRESULT hr)
  63. //
  64. // History:
  65. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  66. // Created.
  67. //****************************************************************************
  68. void
  69. CIlsUser::NotifyULSRegister(HRESULT hr)
  70. {
  71. g_pCIls->LocalAsyncRespond(WM_ILS_LOCAL_REGISTER, m_uReqID, hr);
  72. m_uReqID = 0;
  73. return;
  74. }
  75. //****************************************************************************
  76. // void
  77. // CIlsUser::NotifyULSUnregister(HRESULT hr)
  78. //
  79. // History:
  80. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  81. // Created.
  82. //****************************************************************************
  83. void
  84. CIlsUser::NotifyULSUnregister(HRESULT hr)
  85. {
  86. g_pCIls->LocalAsyncRespond(WM_ILS_LOCAL_UNREGISTER, m_uReqID, hr);
  87. m_uReqID = 0;
  88. return;
  89. }
  90. //****************************************************************************
  91. // STDMETHODIMP
  92. // CIlsUser::AddPendingRequest(ULONG uReqType, ULONG uMsgID)
  93. //
  94. // History:
  95. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  96. // Created.
  97. //****************************************************************************
  98. HRESULT CIlsUser::
  99. AddPendingRequest(ULONG uReqType, ULONG uMsgID)
  100. {
  101. // Add the request to the queue
  102. //
  103. COM_REQ_INFO ri;
  104. ReqInfo_Init (&ri);
  105. ri.uReqType = uReqType;
  106. ri.uMsgID = uMsgID;
  107. ReqInfo_SetUser (&ri, this);
  108. HRESULT hr = g_pReqMgr->NewRequest(&ri);
  109. if (SUCCEEDED(hr))
  110. {
  111. // Make sure the objects do not disappear before we get the response
  112. //
  113. this->AddRef();
  114. // Remember the last request
  115. //
  116. m_uLastMsgID = uMsgID;
  117. }
  118. return hr;
  119. }
  120. //****************************************************************************
  121. // STDMETHODIMP
  122. // CIlsUser::Register (CIlsUser *pUser, CLocalApp *pApp, ULONG uReqID)
  123. //
  124. // History:
  125. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  126. // Created.
  127. //****************************************************************************
  128. HRESULT CIlsUser::
  129. InternalRegister ( ULONG uReqID )
  130. {
  131. LDAP_ASYNCINFO lai;
  132. PLDAP_CLIENTINFO pui;
  133. HANDLE hUser;
  134. HRESULT hr;
  135. ASSERT(uReqID != 0);
  136. // Validate the proper state
  137. //
  138. if (m_uState != ULSSVR_INIT)
  139. return ILS_E_FAIL;
  140. // Get the protocol enumerator
  141. //
  142. hr = EnumLocalProtocols(&m_pep);
  143. if (SUCCEEDED(hr))
  144. {
  145. // Remember the request ID
  146. //
  147. m_uReqID = uReqID;
  148. // Start the registration state machine
  149. //
  150. hr = InternalRegisterNext (NOERROR);
  151. };
  152. return hr;
  153. }
  154. //****************************************************************************
  155. // STDMETHODIMP
  156. // CIlsUser::InternalRegisterNext (HRESULT hr)
  157. //
  158. // History:
  159. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  160. // Created.
  161. //****************************************************************************
  162. HRESULT CIlsUser::
  163. InternalRegisterNext (HRESULT hr)
  164. {
  165. // lonchanc:
  166. // I need to change Viroon's logic here.
  167. // We should simply send out a bunch of requests and
  168. // wait for all of them to come back, rather than
  169. // doing a state machine stuff!!!
  170. LDAP_ASYNCINFO lai;
  171. ULONG uReqType;
  172. // Clean up last request
  173. //
  174. m_uLastMsgID = 0;
  175. if (SUCCEEDED(hr))
  176. {
  177. switch (m_uState)
  178. {
  179. case ULSSVR_INIT:
  180. {
  181. PLDAP_CLIENTINFO pui;
  182. HANDLE hUser;
  183. // Snap-shot the user information now
  184. //
  185. hr = InternalGetUserInfo (TRUE, &pui, LU_MOD_ALL);
  186. if (SUCCEEDED(hr))
  187. {
  188. // Register the user with the server
  189. //
  190. hr = ::UlsLdap_RegisterClient ( (DWORD_PTR) this,
  191. m_pIlsServer->GetServerInfo (),
  192. pui,
  193. &hUser,
  194. &lai);
  195. if (SUCCEEDED(hr))
  196. {
  197. // We are registering the user
  198. //
  199. m_hLdapUser = hUser;
  200. m_uState = ULSSVR_REG_USER;
  201. uReqType = WM_ILS_REGISTER_CLIENT;
  202. };
  203. ::MemFree (pui);
  204. };
  205. break;
  206. }
  207. case ULSSVR_REG_USER:
  208. m_uState = ULSSVR_REG_PROT;
  209. //
  210. // Fall through to start registering the protocol
  211. //
  212. case ULSSVR_REG_PROT:
  213. {
  214. IIlsProtocol *plp;
  215. // Get the next protocol from the application
  216. //
  217. ASSERT (m_pep != NULL);
  218. hr = m_pep->Next(1, &plp, NULL);
  219. switch (hr)
  220. {
  221. case NOERROR:
  222. {
  223. ASSERT (plp != NULL);
  224. hr = RegisterLocalProtocol(FALSE, (CLocalProt *)plp, &lai);
  225. plp->Release (); // AddRef by m_pep->Next()
  226. uReqType = WM_ILS_REGISTER_PROTOCOL;
  227. break;
  228. }
  229. case S_FALSE:
  230. {
  231. // The last protocol is done. Cleanup enumerator
  232. //
  233. m_pep->Release();
  234. m_pep = NULL;
  235. // Change to connect state and notify the ULS object
  236. // We are done. Get out of here.
  237. //
  238. hr = NOERROR;
  239. m_uState = ULSSVR_CONNECT;
  240. NotifyULSRegister(NOERROR);
  241. return NOERROR;
  242. }
  243. default:
  244. {
  245. // Fail the enumeration, bail out
  246. //
  247. break;
  248. }
  249. };
  250. break;
  251. }
  252. default:
  253. ASSERT(0);
  254. break;
  255. };
  256. };
  257. if (SUCCEEDED(hr))
  258. {
  259. // Add a pending request to handle the response
  260. //
  261. hr = AddPendingRequest(uReqType, lai.uMsgID);
  262. };
  263. if (FAILED(hr))
  264. {
  265. // Oops ! the server failed us. Clean up the registration
  266. //
  267. InternalCleanupRegistration (TRUE);
  268. // Notify the ULS object for the failure
  269. //
  270. NotifyULSRegister(hr);
  271. };
  272. return NOERROR;
  273. }
  274. //****************************************************************************
  275. // STDMETHODIMP
  276. // CIlsUser::CleanupRegistration (void)
  277. //
  278. // History:
  279. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  280. // Created.
  281. //****************************************************************************
  282. HRESULT
  283. CIlsUser::InternalCleanupRegistration ( BOOL fKeepProtList )
  284. {
  285. LDAP_ASYNCINFO lai;
  286. // Note: This is a fast cleanup. The idea is to unregister everything being
  287. // registered so far without waiting for the unregister result.
  288. //
  289. // Unregister each registered protocol
  290. //
  291. CLocalProt *plp = NULL;
  292. HANDLE hEnum = NULL;
  293. m_ProtList.Enumerate(&hEnum);
  294. if (fKeepProtList)
  295. {
  296. while (m_ProtList.Next (&hEnum, (VOID **) &plp) == NOERROR)
  297. {
  298. ASSERT (plp != NULL);
  299. ::UlsLdap_VirtualUnRegisterProtocol(plp->GetProviderHandle());
  300. plp->SetProviderHandle (NULL);
  301. }
  302. }
  303. else
  304. {
  305. while(m_ProtList.Next (&hEnum, (VOID **) &plp) == NOERROR)
  306. {
  307. ASSERT (plp != NULL);
  308. ::UlsLdap_UnRegisterProtocol (plp->GetProviderHandle (), &lai);
  309. plp->Release();
  310. }
  311. m_ProtList.Flush ();
  312. }
  313. //
  314. // Unregister user
  315. //
  316. if (m_hLdapUser != NULL)
  317. {
  318. ::UlsLdap_UnRegisterClient (m_hLdapUser, &lai);
  319. m_hLdapUser = NULL;
  320. };
  321. // Release all the resource
  322. //
  323. if (m_pep != NULL)
  324. {
  325. m_pep->Release();
  326. m_pep = NULL;
  327. };
  328. // Unwind the object to the initialize state
  329. //
  330. m_uState = ULSSVR_INIT;
  331. return NOERROR;
  332. }
  333. //****************************************************************************
  334. // STDMETHODIMP
  335. // CIlsUser::Unregister (ULONG uReqID)
  336. //
  337. // History:
  338. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  339. // Created.
  340. //****************************************************************************
  341. HRESULT
  342. CIlsUser::InternalUnregister (ULONG uReqID)
  343. {
  344. HRESULT hr;
  345. ASSERT(uReqID != 0);
  346. // Remove the last request, if any
  347. //
  348. if (m_uLastMsgID != 0)
  349. {
  350. COM_REQ_INFO ri;
  351. ReqInfo_Init (&ri);
  352. // Look for the matching request information
  353. //
  354. ri.uReqID = 0;
  355. ri.uMsgID = m_uLastMsgID;
  356. g_pReqMgr->RequestDone(&ri);
  357. };
  358. // If this is to cancel the current registration, we need to cancel the
  359. // registration then start unregistration.
  360. //
  361. if (m_uReqID != 0)
  362. {
  363. NotifyULSRegister(ILS_E_ABORT);
  364. };
  365. // Determine the starting state
  366. //
  367. hr = NOERROR;
  368. switch (m_uState)
  369. {
  370. case ULSSVR_RELOGON:
  371. case ULSSVR_NETWORK_DOWN:
  372. case ULSSVR_CONNECT:
  373. case ULSSVR_REG_PROT:
  374. //
  375. // In the middle of registering a protocol or an app
  376. // Unregistering the protocol then the app
  377. //
  378. m_uState = ULSSVR_UNREG_PROT;
  379. break;
  380. case ULSSVR_REG_USER:
  381. //
  382. // In the middle of registering the user
  383. // Unregistering the user
  384. //
  385. m_uState = ULSSVR_UNREG_USER;
  386. break;
  387. default:
  388. hr = ILS_E_FAIL;
  389. break;
  390. }
  391. // The initial request succeeds, remember the request ID
  392. //
  393. if (SUCCEEDED(hr))
  394. {
  395. // lonchanc: [11/15/96]
  396. // To fix the "OnLocalRegisterResult: No pending request for 0" problem,
  397. // we have to put uReqID because UnregisterNext() will use uReqID when
  398. // it fails to unregister app/user.
  399. //
  400. m_uReqID = uReqID;
  401. hr = InternalUnregisterNext(hr);
  402. #if 0 // lonchanc: [11/15/96]
  403. // See the comment above.
  404. if (SUCCEEDED(hr))
  405. {
  406. m_uReqID = uReqID;
  407. };
  408. #endif
  409. };
  410. return hr;
  411. }
  412. //****************************************************************************
  413. // STDMETHODIMP
  414. // CIlsUser::InternalUnregisterNext (HRESULT hr)
  415. //
  416. // History:
  417. // Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
  418. // Created.
  419. //****************************************************************************
  420. HRESULT
  421. CIlsUser::InternalUnregisterNext (HRESULT hr)
  422. {
  423. LDAP_ASYNCINFO lai;
  424. ULONG uReqType;
  425. // Clean up last request
  426. //
  427. m_uLastMsgID = 0;
  428. do
  429. {
  430. switch (m_uState)
  431. {
  432. case ULSSVR_UNREG_PROT:
  433. {
  434. // Is there another protocol?
  435. //
  436. CLocalProt *plp = NULL;
  437. HANDLE hEnum = NULL;
  438. m_ProtList.Enumerate(&hEnum);
  439. while (m_ProtList.Next(&hEnum, (VOID **)&plp) == S_OK)
  440. {
  441. // Do not need to unregister protocols because
  442. // UnregisterUser will delete the entire entry.
  443. //
  444. ::UlsLdap_VirtualUnRegisterProtocol (plp->GetProviderHandle());
  445. // Another protocol to clean up
  446. //
  447. plp->SetProviderHandle (NULL);
  448. // Do not need to plp->Release() (cf. AddRef by RegisterLocalProtocol)
  449. // because the user object still contain all the protocol objects
  450. //
  451. }
  452. // Unregister the user
  453. //
  454. m_uState = ULSSVR_UNREG_USER;
  455. hr = ::UlsLdap_UnRegisterClient (m_hLdapUser, &lai);
  456. uReqType = WM_ILS_UNREGISTER_CLIENT;
  457. m_hLdapUser = NULL;
  458. break;
  459. }
  460. case ULSSVR_UNREG_USER:
  461. //
  462. // Put the object back into the init state
  463. //
  464. InternalCleanupRegistration(TRUE);
  465. NotifyULSUnregister(NOERROR);
  466. return NOERROR;
  467. default:
  468. ASSERT(0);
  469. return NOERROR;
  470. };
  471. }
  472. while (FAILED(hr)); // Unregistration failed, nohing to wait for
  473. if (SUCCEEDED(hr))
  474. {
  475. AddPendingRequest(uReqType, lai.uMsgID);
  476. };
  477. return hr;
  478. }
  479.