|
|
//****************************************************************************
//
// Module: ULS.DLL
// File: cserver.cpp
// Content: This file contains the ULS server object.
// History:
// Wed 17-Apr-1996 11:13:54 -by- Viroon Touranachun [viroont]
//
// Copyright (c) Microsoft Corporation 1996-1997
//
//****************************************************************************
#include "ulsp.h"
#include "culs.h"
#include "localusr.h"
#include "attribs.h"
#include "localprt.h"
#include "callback.h"
//****************************************************************************
// ILS_STATE
// CIlsUser::GetULSState(VOID)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
ILS_STATE CIlsUser:: GetULSState ( VOID ) { ILS_STATE uULSState;
switch(m_uState) { case ULSSVR_INVALID: case ULSSVR_INIT: uULSState = ILS_UNREGISTERED; break;
case ULSSVR_REG_USER: case ULSSVR_REG_PROT: uULSState = ILS_REGISTERING; break;
case ULSSVR_CONNECT: uULSState = ILS_REGISTERED; break;
case ULSSVR_UNREG_PROT: case ULSSVR_UNREG_USER: uULSState = ILS_UNREGISTERING; break;
case ULSSVR_RELOGON: uULSState = ILS_REGISTERED_BUT_INVALID; break;
case ULSSVR_NETWORK_DOWN: uULSState = ILS_NETWORK_DOWN; break;
default: ASSERT(0); uULSState = ILS_UNREGISTERED; break; };
return uULSState; }
//****************************************************************************
// void
// CIlsUser::NotifyULSRegister(HRESULT hr)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
void CIlsUser::NotifyULSRegister(HRESULT hr) { g_pCIls->LocalAsyncRespond(WM_ILS_LOCAL_REGISTER, m_uReqID, hr); m_uReqID = 0; return; }
//****************************************************************************
// void
// CIlsUser::NotifyULSUnregister(HRESULT hr)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
void CIlsUser::NotifyULSUnregister(HRESULT hr) { g_pCIls->LocalAsyncRespond(WM_ILS_LOCAL_UNREGISTER, m_uReqID, hr); m_uReqID = 0; return; }
//****************************************************************************
// STDMETHODIMP
// CIlsUser::AddPendingRequest(ULONG uReqType, ULONG uMsgID)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
HRESULT CIlsUser:: AddPendingRequest(ULONG uReqType, ULONG uMsgID) { // Add the request to the queue
//
COM_REQ_INFO ri; ReqInfo_Init (&ri);
ri.uReqType = uReqType; ri.uMsgID = uMsgID;
ReqInfo_SetUser (&ri, this);
HRESULT hr = g_pReqMgr->NewRequest(&ri); if (SUCCEEDED(hr)) { // Make sure the objects do not disappear before we get the response
//
this->AddRef();
// Remember the last request
//
m_uLastMsgID = uMsgID; }
return hr; }
//****************************************************************************
// STDMETHODIMP
// CIlsUser::Register (CIlsUser *pUser, CLocalApp *pApp, ULONG uReqID)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
HRESULT CIlsUser:: InternalRegister ( ULONG uReqID ) { LDAP_ASYNCINFO lai; PLDAP_CLIENTINFO pui; HANDLE hUser; HRESULT hr;
ASSERT(uReqID != 0);
// Validate the proper state
//
if (m_uState != ULSSVR_INIT) return ILS_E_FAIL;
// Get the protocol enumerator
//
hr = EnumLocalProtocols(&m_pep); if (SUCCEEDED(hr)) { // Remember the request ID
//
m_uReqID = uReqID;
// Start the registration state machine
//
hr = InternalRegisterNext (NOERROR); };
return hr; }
//****************************************************************************
// STDMETHODIMP
// CIlsUser::InternalRegisterNext (HRESULT hr)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
HRESULT CIlsUser:: InternalRegisterNext (HRESULT hr) { // lonchanc:
// I need to change Viroon's logic here.
// We should simply send out a bunch of requests and
// wait for all of them to come back, rather than
// doing a state machine stuff!!!
LDAP_ASYNCINFO lai; ULONG uReqType;
// Clean up last request
//
m_uLastMsgID = 0;
if (SUCCEEDED(hr)) { switch (m_uState) { case ULSSVR_INIT: { PLDAP_CLIENTINFO pui; HANDLE hUser;
// Snap-shot the user information now
//
hr = InternalGetUserInfo (TRUE, &pui, LU_MOD_ALL);
if (SUCCEEDED(hr)) { // Register the user with the server
//
hr = ::UlsLdap_RegisterClient ( (DWORD_PTR) this, m_pIlsServer->GetServerInfo (), pui, &hUser, &lai); if (SUCCEEDED(hr)) { // We are registering the user
//
m_hLdapUser = hUser; m_uState = ULSSVR_REG_USER; uReqType = WM_ILS_REGISTER_CLIENT; }; ::MemFree (pui); }; break; }
case ULSSVR_REG_USER:
m_uState = ULSSVR_REG_PROT; //
// Fall through to start registering the protocol
//
case ULSSVR_REG_PROT: { IIlsProtocol *plp;
// Get the next protocol from the application
//
ASSERT (m_pep != NULL); hr = m_pep->Next(1, &plp, NULL);
switch (hr) { case NOERROR: { ASSERT (plp != NULL); hr = RegisterLocalProtocol(FALSE, (CLocalProt *)plp, &lai); plp->Release (); // AddRef by m_pep->Next()
uReqType = WM_ILS_REGISTER_PROTOCOL; break; } case S_FALSE: { // The last protocol is done. Cleanup enumerator
//
m_pep->Release(); m_pep = NULL;
// Change to connect state and notify the ULS object
// We are done. Get out of here.
//
hr = NOERROR; m_uState = ULSSVR_CONNECT; NotifyULSRegister(NOERROR); return NOERROR; } default: { // Fail the enumeration, bail out
//
break; } }; break; } default: ASSERT(0); break; }; };
if (SUCCEEDED(hr)) { // Add a pending request to handle the response
//
hr = AddPendingRequest(uReqType, lai.uMsgID); };
if (FAILED(hr)) { // Oops ! the server failed us. Clean up the registration
//
InternalCleanupRegistration (TRUE);
// Notify the ULS object for the failure
//
NotifyULSRegister(hr); }; return NOERROR; }
//****************************************************************************
// STDMETHODIMP
// CIlsUser::CleanupRegistration (void)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
HRESULT CIlsUser::InternalCleanupRegistration ( BOOL fKeepProtList ) { LDAP_ASYNCINFO lai;
// Note: This is a fast cleanup. The idea is to unregister everything being
// registered so far without waiting for the unregister result.
//
// Unregister each registered protocol
//
CLocalProt *plp = NULL; HANDLE hEnum = NULL; m_ProtList.Enumerate(&hEnum); if (fKeepProtList) { while (m_ProtList.Next (&hEnum, (VOID **) &plp) == NOERROR) { ASSERT (plp != NULL); ::UlsLdap_VirtualUnRegisterProtocol(plp->GetProviderHandle()); plp->SetProviderHandle (NULL); } } else { while(m_ProtList.Next (&hEnum, (VOID **) &plp) == NOERROR) { ASSERT (plp != NULL); ::UlsLdap_UnRegisterProtocol (plp->GetProviderHandle (), &lai); plp->Release(); } m_ProtList.Flush (); }
//
// Unregister user
//
if (m_hLdapUser != NULL) { ::UlsLdap_UnRegisterClient (m_hLdapUser, &lai); m_hLdapUser = NULL; };
// Release all the resource
//
if (m_pep != NULL) { m_pep->Release(); m_pep = NULL; };
// Unwind the object to the initialize state
//
m_uState = ULSSVR_INIT; return NOERROR; }
//****************************************************************************
// STDMETHODIMP
// CIlsUser::Unregister (ULONG uReqID)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
HRESULT CIlsUser::InternalUnregister (ULONG uReqID) { HRESULT hr;
ASSERT(uReqID != 0);
// Remove the last request, if any
//
if (m_uLastMsgID != 0) { COM_REQ_INFO ri; ReqInfo_Init (&ri);
// Look for the matching request information
//
ri.uReqID = 0; ri.uMsgID = m_uLastMsgID;
g_pReqMgr->RequestDone(&ri); };
// If this is to cancel the current registration, we need to cancel the
// registration then start unregistration.
//
if (m_uReqID != 0) { NotifyULSRegister(ILS_E_ABORT); };
// Determine the starting state
//
hr = NOERROR; switch (m_uState) { case ULSSVR_RELOGON: case ULSSVR_NETWORK_DOWN:
case ULSSVR_CONNECT: case ULSSVR_REG_PROT: //
// In the middle of registering a protocol or an app
// Unregistering the protocol then the app
//
m_uState = ULSSVR_UNREG_PROT; break;
case ULSSVR_REG_USER: //
// In the middle of registering the user
// Unregistering the user
//
m_uState = ULSSVR_UNREG_USER; break;
default: hr = ILS_E_FAIL; break; }
// The initial request succeeds, remember the request ID
//
if (SUCCEEDED(hr)) { // lonchanc: [11/15/96]
// To fix the "OnLocalRegisterResult: No pending request for 0" problem,
// we have to put uReqID because UnregisterNext() will use uReqID when
// it fails to unregister app/user.
//
m_uReqID = uReqID; hr = InternalUnregisterNext(hr);
#if 0 // lonchanc: [11/15/96]
// See the comment above.
if (SUCCEEDED(hr)) { m_uReqID = uReqID; }; #endif
}; return hr; }
//****************************************************************************
// STDMETHODIMP
// CIlsUser::InternalUnregisterNext (HRESULT hr)
//
// History:
// Wed 17-Apr-1996 11:14:08 -by- Viroon Touranachun [viroont]
// Created.
//****************************************************************************
HRESULT CIlsUser::InternalUnregisterNext (HRESULT hr) { LDAP_ASYNCINFO lai; ULONG uReqType;
// Clean up last request
//
m_uLastMsgID = 0;
do { switch (m_uState) { case ULSSVR_UNREG_PROT: { // Is there another protocol?
//
CLocalProt *plp = NULL; HANDLE hEnum = NULL; m_ProtList.Enumerate(&hEnum); while (m_ProtList.Next(&hEnum, (VOID **)&plp) == S_OK) { // Do not need to unregister protocols because
// UnregisterUser will delete the entire entry.
//
::UlsLdap_VirtualUnRegisterProtocol (plp->GetProviderHandle());
// Another protocol to clean up
//
plp->SetProviderHandle (NULL);
// Do not need to plp->Release() (cf. AddRef by RegisterLocalProtocol)
// because the user object still contain all the protocol objects
//
}
// Unregister the user
//
m_uState = ULSSVR_UNREG_USER; hr = ::UlsLdap_UnRegisterClient (m_hLdapUser, &lai); uReqType = WM_ILS_UNREGISTER_CLIENT; m_hLdapUser = NULL; break; }
case ULSSVR_UNREG_USER: //
// Put the object back into the init state
//
InternalCleanupRegistration(TRUE); NotifyULSUnregister(NOERROR); return NOERROR;
default: ASSERT(0); return NOERROR; }; } while (FAILED(hr)); // Unregistration failed, nohing to wait for
if (SUCCEEDED(hr)) { AddPendingRequest(uReqType, lai.uMsgID); }; return hr; }
|