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

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. #include "precomp.h"
  3. #ifdef EXT_DEBUG
  4. #undef THIS_FILE
  5. static char THIS_FILE[] = __FILE__;
  6. #endif
  7. #include "ConnectThread.h"
  8. #include <process.h>
  9. #include "..\common\T_DataExtractor.h"
  10. #include <cominit.h>
  11. #include <stdio.h>
  12. #include "util.h"
  13. //const wchar_t* MMC_SNAPIN_MACHINE_NAME = L"MMC_SNAPIN_MACHINE_NAME";
  14. CLIPFORMAT WbemConnectThread::MACHINE_NAME_1 = 0;
  15. //--------------------------
  16. WbemConnectThread::WbemConnectThread()
  17. {
  18. m_cRef = 1;
  19. m_hr = 0;
  20. m_status = notStarted;
  21. MACHINE_NAME_1 = (CLIPFORMAT) RegisterClipboardFormat(_T("MMC_SNAPIN_MACHINE_NAME"));
  22. m_machineName = L"AGAINWITHTEKLINGONS";
  23. m_credentials = 0;
  24. m_doWork = CreateEvent(NULL, FALSE, FALSE, NULL);
  25. m_threadCmd = false;
  26. m_hThread = 0;
  27. }
  28. //----------------------------------------------------------------
  29. WbemConnectThread::~WbemConnectThread()
  30. {
  31. m_hr = 0;
  32. m_status = notStarted;
  33. m_notify.RemoveAll();
  34. if(m_hThread)
  35. {
  36. //TODO: If the thread is running we will have to terminate it.
  37. m_threadCmd = CT_EXIT;
  38. SetEvent(m_doWork);
  39. WaitForSingleObject((HANDLE)m_hThread, 5000);
  40. }
  41. if(m_doWork)
  42. {
  43. CloseHandle(m_doWork);
  44. m_doWork = 0;
  45. }
  46. if (m_credentials)
  47. {
  48. WbemFreeAuthIdentity(m_credentials->authIdent);
  49. m_credentials->authIdent = 0;
  50. };
  51. }
  52. //----------------------------------------------------------------
  53. typedef struct
  54. {
  55. wchar_t t[MAXCOMPUTER_NAME + 1];
  56. } test;
  57. //TODO: I don't know what this function does. But will try to find out
  58. void WbemConnectThread::MachineName(IDataObject *_pDataObject, bstr_t *name)
  59. {
  60. HGLOBAL hMem = GlobalAlloc(GMEM_SHARE,sizeof(test));
  61. wchar_t *pRet = NULL;
  62. HRESULT hr = 0;
  63. if(hMem != NULL)
  64. {
  65. STGMEDIUM stgmedium = { TYMED_HGLOBAL, (HBITMAP) hMem};
  66. FORMATETC formatetc = { MACHINE_NAME_1,
  67. NULL,
  68. DVASPECT_CONTENT,
  69. -1,
  70. TYMED_HGLOBAL };
  71. if((hr = _pDataObject->GetDataHere(&formatetc, &stgmedium)) == S_OK )
  72. {
  73. *name = bstr_t((wchar_t *)hMem);
  74. }
  75. GlobalFree(hMem);
  76. }
  77. }
  78. //----------------------------------------------------------
  79. HRESULT WbemConnectThread::EnsureThread(void)
  80. {
  81. HRESULT retval = S_OK;
  82. if(m_hThread == 0)
  83. {
  84. // let the thread do the connect. The CWbemService class will
  85. // handle marshalling as its used by other threads.
  86. if((m_hThread = _beginthread(WbemConnectThreadProc, 0, (LPVOID)this)) == -1)
  87. {
  88. m_status = threadError;
  89. retval = E_FAIL;
  90. }
  91. }
  92. return retval;
  93. }
  94. //----------------------------------------------------------
  95. HRESULT WbemConnectThread::Connect(bstr_t machineName,
  96. bstr_t ns,
  97. bool threaded /* = true */,
  98. LOGIN_CREDENTIALS *credentials /* = NULL */)
  99. {
  100. m_nameSpace = ns;
  101. if((m_credentials != credentials) &&
  102. m_credentials && m_credentials->authIdent)
  103. {
  104. WbemFreeAuthIdentity(m_credentials->authIdent);
  105. m_credentials->authIdent = 0;
  106. }
  107. if(machineName.length() > 0)
  108. {
  109. m_credentials = credentials;
  110. }
  111. else
  112. {
  113. m_credentials = 0;
  114. }
  115. m_hr = 0;
  116. if(credentials)
  117. {
  118. m_machineName = _T("AGAINWITHTEKLINGONS"); // force a reconnect to
  119. // the same machine.
  120. }
  121. // put the name together.
  122. bstr_t newMachine;
  123. // disconnect from the old machine.
  124. DisconnectServer();
  125. m_machineName = machineName;
  126. int x;
  127. // if machine is whacked already...
  128. if(_tcsncmp(m_machineName, _T("\\"), 1) == 0)
  129. {
  130. // use it.
  131. m_nameSpace = m_machineName;
  132. if(((TCHAR*)ns != NULL) && (_tcslen(ns) > 0))
  133. {
  134. if(((LPCTSTR)ns)[0] != _T('\\')) // namespace is whacked.
  135. {
  136. m_nameSpace += _T("\\");
  137. }
  138. }
  139. m_nameSpace += ns;
  140. }
  141. else if(((x = m_machineName.length()) > 0))
  142. {
  143. // whack it myself.
  144. m_nameSpace = "\\\\";
  145. m_nameSpace += m_machineName;
  146. if(((LPCTSTR)ns)[0] != _T('\\')) // namespace is whacked.
  147. {
  148. m_nameSpace += _T("\\");
  149. }
  150. m_nameSpace += ns;
  151. }
  152. else
  153. {
  154. m_nameSpace = ns;
  155. }
  156. EnsureThread();
  157. m_threadCmd = CT_CONNECT;
  158. SetEvent(m_doWork);
  159. return E_FAIL;
  160. }
  161. bool WbemConnectThread::Connect(IDataObject *_pDataObject,
  162. HWND *hWnd /* = 0 */)
  163. {
  164. m_nameSpace = "root\\cimv2";
  165. // put the name together.
  166. bstr_t newMachine;
  167. MachineName(_pDataObject, &newMachine);
  168. if(!newMachine) return false;
  169. // if reconnecting to another machine...
  170. if(newMachine != m_machineName)
  171. {
  172. // disconnect from the old machine.
  173. DisconnectServer();
  174. m_machineName = newMachine;
  175. int x;
  176. // if its whacked already...
  177. if(_tcsncmp((LPCTSTR)m_machineName, _T("\\"), 1) == 0)
  178. {
  179. // use it.
  180. m_nameSpace = m_machineName;
  181. m_nameSpace += "\\root\\cimv2";
  182. }
  183. else if(((x = m_machineName.length()) > 0))
  184. {
  185. // whack it myself.
  186. m_nameSpace = "\\\\";
  187. m_nameSpace += m_machineName;
  188. m_nameSpace += "\\root\\cimv2";
  189. }
  190. EnsureThread();
  191. m_threadCmd = CT_CONNECT;
  192. NotifyWhenDone(hWnd);
  193. SetEvent(m_doWork);
  194. return true; //TODO: check this return value
  195. }
  196. else
  197. {
  198. // reconnecting to the same machine-- lie!!
  199. return true;
  200. }
  201. return false;
  202. }
  203. //----------------------------------------------------------
  204. // Returns true if a msg will be sent.
  205. // Returns false if its already over.
  206. bool WbemConnectThread::NotifyWhenDone(HWND *dlg)
  207. {
  208. switch(m_status)
  209. {
  210. case notStarted:
  211. case locating:
  212. case connecting:
  213. m_notify.Add(dlg);
  214. return true;
  215. case ready:
  216. case error:
  217. case cancelled:
  218. return false;
  219. }; // endswitch
  220. return false;
  221. }
  222. //------------------------------------------------
  223. bool WbemConnectThread::isLocalConnection(void)
  224. {
  225. return (m_machineName.length() == 0);
  226. }
  227. //------------------------------------------------
  228. void WbemConnectThread::Cancel(void)
  229. {
  230. m_status = cancelled;
  231. m_hr = WBEM_S_OPERATION_CANCELLED;
  232. Notify(0);
  233. m_machineName = L"AGAINWITHTEKLINGONS";
  234. }
  235. //------------------------------------------------
  236. void WbemConnectThread::DisconnectServer(void)
  237. {
  238. m_status = notStarted;
  239. m_notify.RemoveAll();
  240. m_machineName = L"AGAINWITHTEKLINGONS";
  241. m_WbemServices.DisconnectServer();
  242. }
  243. //------------------------------------------------
  244. void WbemConnectThread::Notify(IStream *stream)
  245. {
  246. HWND *hwnd;
  247. for(int i = 0; i < m_notify.GetSize(); i++)
  248. {
  249. hwnd = m_notify[i];
  250. if(hwnd && *hwnd)
  251. {
  252. PostMessage(*hwnd,
  253. WM_ASYNC_CIMOM_CONNECTED,
  254. 0, (LPARAM)stream);
  255. }
  256. }
  257. m_notify.RemoveAll();
  258. }
  259. //-----------------------------------------------------------------
  260. void WbemConnectThread::SendPtr(HWND hwnd)
  261. {
  262. EnsureThread();
  263. m_hWndGetPtr = hwnd;
  264. m_threadCmd = CT_SEND_PTR;
  265. SetEvent(m_doWork);
  266. }
  267. //-----------------------------------------------------------------
  268. HRESULT WbemConnectThread::ConnectNow()
  269. {
  270. HRESULT retval = E_FAIL;
  271. m_status = connecting;
  272. try
  273. {
  274. m_hr = m_WbemServices.ConnectServer(m_nameSpace, m_credentials);
  275. }
  276. catch(CWbemException &e)
  277. {
  278. m_status = error;
  279. m_hr = e.GetErrorCode();
  280. }
  281. if(SUCCEEDED(m_hr))
  282. {
  283. m_status = ready;
  284. retval = S_OK;
  285. }
  286. else
  287. {
  288. m_status = error;
  289. }
  290. return retval;
  291. }
  292. void __cdecl WbemConnectThreadProc(LPVOID lpParameter)
  293. {
  294. WbemConnectThread *pThreadObj = (WbemConnectThread *)lpParameter;
  295. pThreadObj->AddRef();
  296. IStream *pStream = 0;
  297. HRESULT hr = S_OK;
  298. HRESULT retval = E_FAIL;
  299. CWbemServices pServices;
  300. CoInitialize(NULL);
  301. MSG msg;
  302. while(true)
  303. {
  304. DWORD res = MsgWaitForMultipleObjects (1,&pThreadObj->m_doWork,
  305. FALSE, -1, QS_ALLINPUT);
  306. if (res == WAIT_OBJECT_0 + 1)
  307. {
  308. while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  309. {
  310. DispatchMessage(&msg);
  311. }
  312. continue;
  313. }
  314. switch(pThreadObj->m_threadCmd)
  315. {
  316. case CT_CONNECT:
  317. {
  318. pStream = 0;
  319. /****************** VINOTH **************************************/
  320. retval = E_FAIL;
  321. pThreadObj->m_status = WbemConnectThread::connecting;
  322. try
  323. {
  324. pThreadObj->m_hr = pServices.ConnectServer(pThreadObj->m_nameSpace, pThreadObj->m_credentials);
  325. }
  326. catch(CWbemException &e)
  327. {
  328. pThreadObj->m_status = WbemConnectThread::error;
  329. pThreadObj->m_hr = e.GetErrorCode();
  330. }
  331. if(SUCCEEDED(pThreadObj->m_hr))
  332. {
  333. pThreadObj->m_status = WbemConnectThread::ready;
  334. retval = S_OK;
  335. }
  336. else
  337. {
  338. pThreadObj->m_status = WbemConnectThread::error;
  339. }
  340. /****************** END *****************************************/
  341. if(SUCCEEDED(retval))
  342. {
  343. IWbemServices *service = 0;
  344. pServices.GetServices(&service);
  345. hr = CoMarshalInterThreadInterfaceInStream(IID_IWbemServices,
  346. service, &pStream);
  347. service->Release();
  348. }
  349. // does someone want a msg?
  350. pThreadObj->Notify(pStream);
  351. break;
  352. }
  353. case CT_SEND_PTR:
  354. if((bool)pServices)
  355. {
  356. IWbemServices *service = 0;
  357. pServices.GetServices(&service);
  358. hr = CoMarshalInterThreadInterfaceInStream(IID_IWbemServices,
  359. service, &pStream);
  360. PostMessage(pThreadObj->m_hWndGetPtr,
  361. WM_ASYNC_CIMOM_CONNECTED,
  362. 0, (LPARAM)pStream);
  363. service->Release();
  364. }
  365. break;
  366. case CT_EXIT:
  367. {
  368. break;
  369. }
  370. }
  371. if(pThreadObj->m_threadCmd == CT_EXIT)
  372. {
  373. pServices = (IWbemServices *)NULL;
  374. break;
  375. }
  376. }
  377. pServices = (IUnknown *)NULL;
  378. pThreadObj->Release();
  379. CoUninitialize();
  380. }