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.
 
 
 
 
 
 

446 lines
9.4 KiB

// Copyright (c) 1997-1999 Microsoft Corporation
#include "precomp.h"
#ifdef EXT_DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "ConnectThread.h"
#include <process.h>
#include "..\common\T_DataExtractor.h"
#include <cominit.h>
#include <stdio.h>
#include "util.h"
//const wchar_t* MMC_SNAPIN_MACHINE_NAME = L"MMC_SNAPIN_MACHINE_NAME";
CLIPFORMAT WbemConnectThread::MACHINE_NAME_1 = 0;
//--------------------------
WbemConnectThread::WbemConnectThread()
{
m_cRef = 1;
m_hr = 0;
m_status = notStarted;
MACHINE_NAME_1 = (CLIPFORMAT) RegisterClipboardFormat(_T("MMC_SNAPIN_MACHINE_NAME"));
m_machineName = L"AGAINWITHTEKLINGONS";
m_credentials = 0;
m_doWork = CreateEvent(NULL, FALSE, FALSE, NULL);
m_threadCmd = false;
m_hThread = 0;
}
//----------------------------------------------------------------
WbemConnectThread::~WbemConnectThread()
{
m_hr = 0;
m_status = notStarted;
m_notify.RemoveAll();
if(m_hThread)
{
//TODO: If the thread is running we will have to terminate it.
m_threadCmd = CT_EXIT;
SetEvent(m_doWork);
WaitForSingleObject((HANDLE)m_hThread, 5000);
}
if(m_doWork)
{
CloseHandle(m_doWork);
m_doWork = 0;
}
if (m_credentials)
{
WbemFreeAuthIdentity(m_credentials->authIdent);
m_credentials->authIdent = 0;
};
}
//----------------------------------------------------------------
typedef struct
{
wchar_t t[MAXCOMPUTER_NAME + 1];
} test;
//TODO: I don't know what this function does. But will try to find out
void WbemConnectThread::MachineName(IDataObject *_pDataObject, bstr_t *name)
{
HGLOBAL hMem = GlobalAlloc(GMEM_SHARE,sizeof(test));
wchar_t *pRet = NULL;
HRESULT hr = 0;
if(hMem != NULL)
{
STGMEDIUM stgmedium = { TYMED_HGLOBAL, (HBITMAP) hMem};
FORMATETC formatetc = { MACHINE_NAME_1,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL };
if((hr = _pDataObject->GetDataHere(&formatetc, &stgmedium)) == S_OK )
{
*name = bstr_t((wchar_t *)hMem);
}
GlobalFree(hMem);
}
}
//----------------------------------------------------------
HRESULT WbemConnectThread::EnsureThread(void)
{
HRESULT retval = S_OK;
if(m_hThread == 0)
{
// let the thread do the connect. The CWbemService class will
// handle marshalling as its used by other threads.
if((m_hThread = _beginthread(WbemConnectThreadProc, 0, (LPVOID)this)) == -1)
{
m_status = threadError;
retval = E_FAIL;
}
}
return retval;
}
//----------------------------------------------------------
HRESULT WbemConnectThread::Connect(bstr_t machineName,
bstr_t ns,
bool threaded /* = true */,
LOGIN_CREDENTIALS *credentials /* = NULL */)
{
m_nameSpace = ns;
if((m_credentials != credentials) &&
m_credentials && m_credentials->authIdent)
{
WbemFreeAuthIdentity(m_credentials->authIdent);
m_credentials->authIdent = 0;
}
if(machineName.length() > 0)
{
m_credentials = credentials;
}
else
{
m_credentials = 0;
}
m_hr = 0;
if(credentials)
{
m_machineName = _T("AGAINWITHTEKLINGONS"); // force a reconnect to
// the same machine.
}
// put the name together.
bstr_t newMachine;
// disconnect from the old machine.
DisconnectServer();
m_machineName = machineName;
int x;
// if machine is whacked already...
if(_tcsncmp(m_machineName, _T("\\"), 1) == 0)
{
// use it.
m_nameSpace = m_machineName;
if(((TCHAR*)ns != NULL) && (_tcslen(ns) > 0))
{
if(((LPCTSTR)ns)[0] != _T('\\')) // namespace is whacked.
{
m_nameSpace += _T("\\");
}
}
m_nameSpace += ns;
}
else if(((x = m_machineName.length()) > 0))
{
// whack it myself.
m_nameSpace = "\\\\";
m_nameSpace += m_machineName;
if(((LPCTSTR)ns)[0] != _T('\\')) // namespace is whacked.
{
m_nameSpace += _T("\\");
}
m_nameSpace += ns;
}
else
{
m_nameSpace = ns;
}
EnsureThread();
m_threadCmd = CT_CONNECT;
SetEvent(m_doWork);
return E_FAIL;
}
bool WbemConnectThread::Connect(IDataObject *_pDataObject,
HWND *hWnd /* = 0 */)
{
m_nameSpace = "root\\cimv2";
// put the name together.
bstr_t newMachine;
MachineName(_pDataObject, &newMachine);
if(!newMachine) return false;
// if reconnecting to another machine...
if(newMachine != m_machineName)
{
// disconnect from the old machine.
DisconnectServer();
m_machineName = newMachine;
int x;
// if its whacked already...
if(_tcsncmp((LPCTSTR)m_machineName, _T("\\"), 1) == 0)
{
// use it.
m_nameSpace = m_machineName;
m_nameSpace += "\\root\\cimv2";
}
else if(((x = m_machineName.length()) > 0))
{
// whack it myself.
m_nameSpace = "\\\\";
m_nameSpace += m_machineName;
m_nameSpace += "\\root\\cimv2";
}
EnsureThread();
m_threadCmd = CT_CONNECT;
NotifyWhenDone(hWnd);
SetEvent(m_doWork);
return true; //TODO: check this return value
}
else
{
// reconnecting to the same machine-- lie!!
return true;
}
return false;
}
//----------------------------------------------------------
// Returns true if a msg will be sent.
// Returns false if its already over.
bool WbemConnectThread::NotifyWhenDone(HWND *dlg)
{
switch(m_status)
{
case notStarted:
case locating:
case connecting:
m_notify.Add(dlg);
return true;
case ready:
case error:
case cancelled:
return false;
}; // endswitch
return false;
}
//------------------------------------------------
bool WbemConnectThread::isLocalConnection(void)
{
return (m_machineName.length() == 0);
}
//------------------------------------------------
void WbemConnectThread::Cancel(void)
{
m_status = cancelled;
m_hr = WBEM_S_OPERATION_CANCELLED;
Notify(0);
m_machineName = L"AGAINWITHTEKLINGONS";
}
//------------------------------------------------
void WbemConnectThread::DisconnectServer(void)
{
m_status = notStarted;
m_notify.RemoveAll();
m_machineName = L"AGAINWITHTEKLINGONS";
m_WbemServices.DisconnectServer();
}
//------------------------------------------------
void WbemConnectThread::Notify(IStream *stream)
{
HWND *hwnd;
for(int i = 0; i < m_notify.GetSize(); i++)
{
hwnd = m_notify[i];
if(hwnd && *hwnd)
{
PostMessage(*hwnd,
WM_ASYNC_CIMOM_CONNECTED,
0, (LPARAM)stream);
}
}
m_notify.RemoveAll();
}
//-----------------------------------------------------------------
void WbemConnectThread::SendPtr(HWND hwnd)
{
EnsureThread();
m_hWndGetPtr = hwnd;
m_threadCmd = CT_SEND_PTR;
SetEvent(m_doWork);
}
//-----------------------------------------------------------------
HRESULT WbemConnectThread::ConnectNow()
{
HRESULT retval = E_FAIL;
m_status = connecting;
try
{
m_hr = m_WbemServices.ConnectServer(m_nameSpace, m_credentials);
}
catch(CWbemException &e)
{
m_status = error;
m_hr = e.GetErrorCode();
}
if(SUCCEEDED(m_hr))
{
m_status = ready;
retval = S_OK;
}
else
{
m_status = error;
}
return retval;
}
void __cdecl WbemConnectThreadProc(LPVOID lpParameter)
{
WbemConnectThread *pThreadObj = (WbemConnectThread *)lpParameter;
pThreadObj->AddRef();
IStream *pStream = 0;
HRESULT hr = S_OK;
HRESULT retval = E_FAIL;
CWbemServices pServices;
CoInitialize(NULL);
MSG msg;
while(true)
{
DWORD res = MsgWaitForMultipleObjects (1,&pThreadObj->m_doWork,
FALSE, -1, QS_ALLINPUT);
if (res == WAIT_OBJECT_0 + 1)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
DispatchMessage(&msg);
}
continue;
}
switch(pThreadObj->m_threadCmd)
{
case CT_CONNECT:
{
pStream = 0;
/****************** VINOTH **************************************/
retval = E_FAIL;
pThreadObj->m_status = WbemConnectThread::connecting;
try
{
pThreadObj->m_hr = pServices.ConnectServer(pThreadObj->m_nameSpace, pThreadObj->m_credentials);
}
catch(CWbemException &e)
{
pThreadObj->m_status = WbemConnectThread::error;
pThreadObj->m_hr = e.GetErrorCode();
}
if(SUCCEEDED(pThreadObj->m_hr))
{
pThreadObj->m_status = WbemConnectThread::ready;
retval = S_OK;
}
else
{
pThreadObj->m_status = WbemConnectThread::error;
}
/****************** END *****************************************/
if(SUCCEEDED(retval))
{
IWbemServices *service = 0;
pServices.GetServices(&service);
hr = CoMarshalInterThreadInterfaceInStream(IID_IWbemServices,
service, &pStream);
service->Release();
}
// does someone want a msg?
pThreadObj->Notify(pStream);
break;
}
case CT_SEND_PTR:
if((bool)pServices)
{
IWbemServices *service = 0;
pServices.GetServices(&service);
hr = CoMarshalInterThreadInterfaceInStream(IID_IWbemServices,
service, &pStream);
PostMessage(pThreadObj->m_hWndGetPtr,
WM_ASYNC_CIMOM_CONNECTED,
0, (LPARAM)pStream);
service->Release();
}
break;
case CT_EXIT:
{
break;
}
}
if(pThreadObj->m_threadCmd == CT_EXIT)
{
pServices = (IWbemServices *)NULL;
break;
}
}
pServices = (IUnknown *)NULL;
pThreadObj->Release();
CoUninitialize();
}