?? exchangeclient.cpp
字號:
CExchangeClient::OnWorkerThreadTermination
Epilogue for the worker thread - notifies callback interface of
client termination
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::OnWorkerThreadTermination()
{
PostMessage(m_hwndCallback, ECM_WORKER_THREAD_TERMINATED, 0, 0);
return S_OK;
}
/*------------------------------------------------------------------------------
CExchangeClient::WorkerThreadProc
The thread proc for the worker thread -
Receives a request from the request queue and processes it - if there are no requests,
waits for a new request or the app to signal the thread to exit.
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::WorkerThreadProc()
{
TRACE();
CExchangeClientRequest *pRequest = NULL;
BOOL fExit = FALSE;
while (!fExit)
{
//First see if we were signaled to exit - otherwise process next request
if (WaitForSingleObject(m_hEventExit, 0) == WAIT_OBJECT_0)
{
fExit = TRUE;
break;
}
//Get the next request from the queue (if it exists)
HRESULT hr = GetNextRequest(&pRequest);
//hr == S_OK if there is a pending request
if (hr == S_OK)
{
SetCurrentRequest(pRequest);
//Tell the request to process itself, with our XMLHttpRequest and Parser
hr = pRequest->Process(
m_cpHttpRequest,
&m_DataRecordParser
);
SetCurrentRequest(NULL);
}
//hr == S_FALSE if there are no requests in the queue
//in this case we should sleep!
else if (hr == S_FALSE)
{
HANDLE rghWait[] = { m_hEventExit, m_hEventNewRequest };
DWORD dwWaitResult = WaitForMultipleObjects(
ARRAYSIZE(rghWait),
rghWait,
FALSE,
INFINITE
);
if (dwWaitResult == WAIT_FAILED)
{
ASSERT(FALSE);
continue;
}
//Determine which event was fired -
HANDLE hEventFired = rghWait[dwWaitResult - WAIT_OBJECT_0];
//Uninitialize has been called - terminate the thread
if (hEventFired == m_hEventExit)
{
fExit = TRUE;
break;
}
//There is a new request in the queue - reset the event and reloop!
else if (hEventFired == m_hEventNewRequest)
{
ResetEvent(m_hEventNewRequest);
continue;
}
}
//Free the request that was just popped off the queue
SafeRelease(pRequest);
}
return S_OK;
}
/*------------------------------------------------------------------------------
CExchangeClient::GetNextRequest
Synchrnonous method for popping the head of the queue
Returns: S_OK if there are items in the queue
S_FALSE if no items in the queue
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::GetNextRequest(CExchangeClientRequest **ppRequest)
{
TRACE();
HRESULT hr = S_OK;
//Check params
if (ppRequest == NULL)
{
ASSERT(FALSE);
return E_POINTER;
}
*ppRequest = NULL;
//Synchronize access to the queue
LockRequests();
if (m_queuePendingRequests.size() > 0)
{
*ppRequest = m_queuePendingRequests.front();
m_queuePendingRequests.pop_front();
}
else
{
hr = S_FALSE;
}
//release the queue lock
UnlockRequests();
return hr;
}
/*------------------------------------------------------------------------------
CExchangeClient::AddNewRequest
Synchronously adds a new request to the queue and signals the worker thread
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::AddNewRequest(CExchangeClientRequest *pRequest)
{
TRACE();
//Check params
if (pRequest == NULL)
{
ASSERT(FALSE);
return E_POINTER;
}
HRESULT hr = S_OK;
//syncronize access to the queue
LockRequests();
if (! m_queuePendingRequests.push_back(pRequest))
{
hr = E_OUTOFMEMORY;
}
else
{
//Add a reference to the object that we placed in the queue
pRequest->AddRef();
//Signal the worker thread
SetEvent(m_hEventNewRequest);
}
//release the queue lock
UnlockRequests();
return hr;
}
/*------------------------------------------------------------------------------
CExchangeClient::CancelCurrentRequest
Cancels the current request (if a request is currently running)
------------------------------------------------------------------------------*/
VOID CExchangeClient::CancelCurrentRequest()
{
LockRequests();
if (m_cpCurrentRequest != NULL)
{
m_cpCurrentRequest->Cancel();
}
UnlockRequests();
}
/*------------------------------------------------------------------------------
CExchangeClient::SetCurrentRequest
Syncronously Sets the current request
------------------------------------------------------------------------------*/
VOID CExchangeClient::SetCurrentRequest(IExchangeClientRequest * piRequest)
{
LockRequests();
m_cpCurrentRequest = piRequest;
UnlockRequests();
}
/*------------------------------------------------------------------------------
CExchangeClient::SetCredentials
Set the username/password of the user
------------------------------------------------------------------------------*/
HRESULT STDMETHODCALLTYPE CExchangeClient::SetCredentials(
const WCHAR * c_wszUsername,
const WCHAR * c_wszPassword
)
{
//check params
if (!m_fInitialized)
{
return OWAEC_E_NOTINITIALIZED;
}
//check params
if (c_wszUsername == NULL || c_wszPassword == NULL)
{
return E_POINTER;
}
HRESULT hr = S_OK;
WCHAR wszUsernameCopy[MAX_PATH] = L"";
WCHAR *pwchUsername = NULL,
*pwchDomain = NULL;
StringCchCopy(wszUsernameCopy, _countof(wszUsernameCopy), c_wszUsername);
//break the username into a domain and a username
WCHAR *pwchDomainUsernameSeparator = wcschr(wszUsernameCopy, L'\\');
if (pwchDomainUsernameSeparator != NULL)
{
pwchDomain = (WCHAR*)wszUsernameCopy;
*pwchDomainUsernameSeparator = 0;
pwchDomainUsernameSeparator++;
pwchUsername = pwchDomainUsernameSeparator;
}
else
{
//point the domain to the null-character at the end
pwchDomain = wszUsernameCopy + wcslen(wszUsernameCopy);
pwchUsername = (WCHAR*)wszUsernameCopy;
}
hr = WriteCredentials(
pwchDomain,
pwchUsername,
c_wszPassword
);
if (SUCCEEDED(hr))
{
//Cancel all requests so that all future requests use new credentials
CancelPendingRequests();
CancelCurrentRequest();
//Remake the http request to remove the credential cookies
hr = RecreateXMLHttpObject();
}
return hr;
}
/*------------------------------------------------------------------------------
CExchangeClient::SetServer
Set the address of the exchange server
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::SetServer(
const WCHAR * c_wszServername
)
{
//check params
if (!m_fInitialized)
{
return OWAEC_E_NOTINITIALIZED;
}
if (c_wszServername == NULL)
{
return E_POINTER;
}
//Cancel all requests so that all requests use the new servername
CancelPendingRequests();
CancelCurrentRequest();
//clear out the old value
m_wstrServer.clear();
//Chop off the ending '/' (if it exists)
INT cchServerName = wcslen(c_wszServername);
if (c_wszServername[cchServerName - 1] == L'/')
{
cchServerName--;
}
//assign the member var with the ending '/' removed (if there)
if (!m_wstrServer.assign(c_wszServername, cchServerName))
{
return E_OUTOFMEMORY;
}
return S_OK;
}
/*------------------------------------------------------------------------------
CExchangeClient::GetServer
Get the server that is currently set in this instance
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::GetServer(
WCHAR * wszBuffer,
UINT cchBuffer
)
{
if (!m_fInitialized)
{
return OWAEC_E_NOTINITIALIZED;
}
if (wszBuffer == NULL)
{
return E_POINTER;
}
if (cchBuffer == 0)
{
return E_INVALIDARG;
}
StringCchCopy(wszBuffer, cchBuffer, m_wstrServer.get_buffer());
return S_OK;
}
/*------------------------------------------------------------------------------
CExchangeClient::Uninitialize
Notifies the worker thread to exit
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::Uninitialize()
{
TRACE();
//Check that we are still initialized
if (!m_fInitialized)
{
return OWAEC_E_NOTINITIALIZED;
}
//cancel all the requests so we can cleanly exit.
CancelPendingRequests();
CancelCurrentRequest();
m_fInitialized = FALSE;
SetEvent(m_hEventExit);
return S_OK;
}
/*------------------------------------------------------------------------------
CExchangeClient::RequestContacts
Asyncronously gets the contacts for the registered user. Results are posted on
the main thread to the callback interface
Parameters:
IN ContactsSearchCriteria to filter contacts by - can be NULL or empty
OUT IExchangeClientRequest that can be used to track the request
Returns (HRESULT): Indicating whether the request has successfully started
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::RequestContacts(
ContactsSearchCriteria *pCriteria,
IExchangeClientRequest **ppiRequest
)
{
TRACE();
HRESULT hr = S_OK;
CContactsFormatHandler *pHandler = NULL;
if (!m_fInitialized)
{
return OWAEC_E_NOTINITIALIZED;
}
if (pCriteria == NULL)
{
return E_POINTER;
}
pHandler = new CContactsFormatHandler;
if (pHandler == NULL)
{
hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
//Dispatch the request
hr = DispatchRequest(
e_ecrtContacts,
reinterpret_cast<VOID*>(pCriteria),
reinterpret_cast<IExchangeClientFormatHandler*>(pHandler),
ppiRequest
);
}
SafeRelease(pHandler);
return hr;
}
/*------------------------------------------------------------------------------
CExchangeClient::RequestGALSearch
Asyncronously searchs the GAL with the specified parameters. Results are posted on
the main thread to the callback interface
Parameters:
OUT IExchangeClientRequest that can be used to track the request
Returns (HRESULT): Indicating whether the request has successfully started
------------------------------------------------------------------------------*/
HRESULT CExchangeClient::RequestGALSearch(
GALSearchCriteria * pCriteria,
IExchangeClientRequest * * ppiRequest
)
{
HRESULT hr = S_OK;
CGALSearchFormatHandler *pHandler = NULL;
if (!m_fInitialized)
{
return OWAEC_E_NOTINITIALIZED;
}
//Check parameters
if (pCriteria == NULL)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -