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.

399 lines
11 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. dialin.cpp
  7. Implementationof CRasDialin class, this class implements COM
  8. interfaces IUnknown, IShellExtInit, IShellPropSheetExt to extend
  9. User object's property sheet.
  10. FILE HISTORY:
  11. */
  12. #include "stdafx.h"
  13. #include "Dialin.h"
  14. #include "DlgDial.h"
  15. #include <dsrole.h>
  16. #include <lmserver.h>
  17. #include <localsec.h>
  18. #include <dsgetdc.h>
  19. #include <mmc.h>
  20. #include <sdowrap.h>
  21. #include "sharesdo.h"
  22. #ifdef __cplusplus
  23. extern "C"{
  24. #endif
  25. #ifndef __IID_DEFINED__
  26. #define __IID_DEFINED__
  27. typedef struct _IID
  28. {
  29. unsigned long x;
  30. unsigned short s1;
  31. unsigned short s2;
  32. unsigned char c[8];
  33. } IID;
  34. #endif // __IID_DEFINED__
  35. #ifndef CLSID_DEFINED
  36. #define CLSID_DEFINED
  37. typedef IID CLSID;
  38. #endif // CLSID_DEFINED
  39. const IID IID_IRasDialin = {0xB52C1E4F,0x1DD2,0x11D1,{0xBC,0x43,0x00,0xC0,0x4F,0xC3,0x1F,0xD3}};
  40. const IID LIBID_RASDIALLib = {0xB52C1E42,0x1DD2,0x11D1,{0xBC,0x43,0x00,0xC0,0x4F,0xC3,0x1F,0xD3}};
  41. const CLSID CLSID_RasDialin = {0xB52C1E50,0x1DD2,0x11D1,{0xBC,0x43,0x00,0xC0,0x4F,0xC3,0x1F,0xD3}};
  42. #ifdef __cplusplus
  43. }
  44. #endif
  45. static ULONG_PTR g_cfMachineName = 0;
  46. static ULONG_PTR g_cfDisplayName = 0;
  47. LONG g_lComponentDataSessions = 0;
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CRasDialin
  50. CRasDialin::CRasDialin()
  51. {
  52. m_pPage = NULL;
  53. m_pMergedPage = NULL;
  54. m_pwszObjName = NULL;
  55. m_pwszClass = NULL;
  56. ZeroMemory(&m_ObjMedium, sizeof(m_ObjMedium));
  57. m_ObjMedium.tymed =TYMED_HGLOBAL;
  58. m_ObjMedium.hGlobal = NULL;
  59. m_bShowPage = TRUE;
  60. }
  61. CRasDialin::~CRasDialin()
  62. {
  63. // stgmedia
  64. // delete m_pPage;
  65. ReleaseStgMedium(&m_ObjMedium);
  66. }
  67. //===============================================================================
  68. // IShellExtInit::Initialize
  69. //
  70. // information of the user object is passed in via parameter pDataObject
  71. // further processing will be based on the DN of the user object
  72. STDMETHODIMP CRasDialin::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hRegKey)
  73. {
  74. TRACE(_T("CRasDialin::Initialize()\r\n"));
  75. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  76. ASSERT (pDataObj != NULL);
  77. // get the object name out of the pDataObj
  78. HRESULT hr = S_OK;
  79. TracePrintf(g_dwTraceHandle, _T("RegisterClipboardFormat %s"),CFSTR_DSOBJECTNAMES);
  80. ULONG_PTR cfDsObjectNames = RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  81. TracePrintf(g_dwTraceHandle, _T(" %x"),cfDsObjectNames);
  82. FORMATETC fmte = {cfDsObjectNames, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  83. LPDSOBJECTNAMES pDsObjectNames;
  84. // Get the path to the DS object from the data object.
  85. // Note: This call runs on the caller's main thread. The pages' window
  86. // procs run on a different thread, so don't reference the data object
  87. // from a winproc unless it is first marshalled on this thread.
  88. TracePrintf(g_dwTraceHandle, _T("pDataObj->GetData returns"));
  89. CHECK_HR(hr = pDataObj->GetData(&fmte, &m_ObjMedium));
  90. TracePrintf(g_dwTraceHandle, _T(" %x"), hr);
  91. pDsObjectNames = (LPDSOBJECTNAMES)m_ObjMedium.hGlobal;
  92. if (pDsObjectNames->cItems < 1)
  93. {
  94. ASSERT (0);
  95. return E_FAIL;
  96. }
  97. m_bShowPage = TRUE;
  98. if(m_bShowPage)
  99. {
  100. // get the name of the object
  101. m_pwszObjName = (LPWSTR)ByteOffset(pDsObjectNames, pDsObjectNames->aObjects[0].offsetName);
  102. // get the class name of the object
  103. m_pwszClass = (LPWSTR)ByteOffset(pDsObjectNames, pDsObjectNames->aObjects[0].offsetClass);
  104. TracePrintf(g_dwTraceHandle, _T("UserPath %s"),m_pwszObjName);
  105. try{
  106. ASSERT(!m_pMergedPage);
  107. CString machineName;
  108. m_pMergedPage = new CDlgRASDialinMerge(RASUSER_ENV_DS, NULL, m_pwszObjName);
  109. TracePrintf(g_dwTraceHandle, _T("new Dialin page object %x"),m_pMergedPage);
  110. ASSERT(m_pMergedPage);
  111. #ifdef SINGLE_SDO_CONNECTION // for share the same sdo connection for multiple users
  112. TracePrintf(g_dwTraceHandle, _T("HrGetDCName returns "));
  113. CHECK_HR(hr = m_pMergedPage->HrGetDCName(machineName));
  114. TracePrintf(g_dwTraceHandle, _T("%x"),hr);
  115. TracePrintf(g_dwTraceHandle, _T("HrGetSharedSdoServer returns "));
  116. // ignore return value:
  117. // reason: marshalling could fail in case this call was made from different thread,
  118. // before the pointer is used, it will be checked again
  119. GetSharedSdoServer((LPCTSTR)machineName, NULL, NULL, NULL, m_pMergedPage->GetMarshalSdoServerHolder());
  120. TracePrintf(g_dwTraceHandle, _T("%x"),hr);
  121. #endif
  122. }
  123. catch(CMemoryException&)
  124. {
  125. CHECK_HR( hr = E_OUTOFMEMORY );
  126. }
  127. }
  128. L_ERR:
  129. TracePrintf(g_dwTraceHandle, _T("%x"),hr);
  130. return hr;
  131. }
  132. //
  133. // FUNCTION: IShellPropSheetExt::AddPages(LPFNADDPROPSHEETPAGE, LPARAM)
  134. //
  135. // PURPOSE: Called by the shell just before the property sheet is displayed.
  136. //
  137. // PARAMETERS:
  138. // lpfnAddPage - Pointer to the Shell's AddPage function
  139. // lParam - Passed as second parameter to lpfnAddPage
  140. //
  141. // RETURN VALUE:
  142. //
  143. // NOERROR in all cases. If for some reason our pages don't get added,
  144. // the Shell still needs to bring up the Properties... sheet.
  145. //
  146. // COMMENTS:
  147. //
  148. STDMETHODIMP CRasDialin::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  149. {
  150. TRACE(_T("CRasDialin::AddPages()\r\n"));
  151. if(!m_bShowPage) return S_OK;
  152. HRESULT hr = S_OK;
  153. // param validation
  154. ASSERT (lpfnAddPage);
  155. if (lpfnAddPage == NULL)
  156. return E_UNEXPECTED;
  157. // make sure our state is fixed up (cause we don't know what context we were called in)
  158. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  159. ASSERT(m_pMergedPage);
  160. // tell MMC to hook the proc because we are running on a separate,
  161. // non MFC thread.
  162. m_pMergedPage->m_psp.pfnCallback = &CDlgRASDialinMerge::PropSheetPageProc;
  163. // We also need to save a self-reference so that the static callback
  164. // function can recover a "this" pointer
  165. m_pMergedPage->m_psp.lParam = (LONG_PTR)m_pMergedPage;
  166. MMCPropPageCallback(&m_pMergedPage->m_psp);
  167. HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(&m_pMergedPage->m_psp);
  168. ASSERT (hPage);
  169. if (hPage == NULL)
  170. return E_UNEXPECTED;
  171. // add the page
  172. lpfnAddPage (hPage, lParam);
  173. m_pPage = NULL; // since it's just consumed by the dialog, cannot added again
  174. return S_OK;
  175. }
  176. //
  177. // FUNCTION: IShellPropSheetExt::ReplacePage(UINT, LPFNADDPROPSHEETPAGE, LPARAM)
  178. //
  179. // PURPOSE: Called by the shell only for Control Panel property sheet
  180. // extensions
  181. //
  182. // PARAMETERS:
  183. // uPageID - ID of page to be replaced
  184. // lpfnReplaceWith - Pointer to the Shell's Replace function
  185. // lParam - Passed as second parameter to lpfnReplaceWith
  186. //
  187. // RETURN VALUE:
  188. //
  189. // E_FAIL, since we don't support this function. It should never be
  190. // called.
  191. // COMMENTS:
  192. //
  193. STDMETHODIMP CRasDialin::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam)
  194. {
  195. TRACE(_T("CRasDialin::ReplacePage()\r\n"));
  196. return E_FAIL;
  197. }
  198. /*---------------------------------------------------------------------------
  199. IExtendPropertySheet Implementation
  200. ---------------------------------------------------------------------------*/
  201. /*!--------------------------------------------------------------------------
  202. IExtendPropertySheet::QueryPagesFor
  203. MMC calls this to see if a node has property pages
  204. Author:
  205. ---------------------------------------------------------------------------*/
  206. STDMETHODIMP
  207. CRasDialin::QueryPagesFor
  208. (
  209. LPDATAOBJECT pDataObject
  210. )
  211. {
  212. return S_OK;
  213. }
  214. /*!--------------------------------------------------------------------------
  215. TFSComponentData::CreatePropertyPages
  216. Implementation of IExtendPropertySheet::CreatePropertyPages
  217. Called for a node to put up property pages
  218. Author:
  219. ---------------------------------------------------------------------------*/
  220. STDMETHODIMP
  221. CRasDialin::CreatePropertyPages
  222. (
  223. LPPROPERTYSHEETCALLBACK lpProvider,
  224. LONG_PTR handle,
  225. LPDATAOBJECT pDataObject
  226. )
  227. {
  228. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  229. FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  230. //STGMEDIUM medium = { TYMED_NULL, NULL, NULL };
  231. STGMEDIUM mediumMachine = { TYMED_HGLOBAL, NULL, NULL };
  232. STGMEDIUM mediumUser = { TYMED_HGLOBAL, NULL, NULL };
  233. HGLOBAL hMem = GlobalAlloc(GMEM_SHARE, MAX_PATH * sizeof(WCHAR));
  234. mediumMachine.hGlobal = hMem;
  235. hMem = GlobalAlloc(GMEM_SHARE, MAX_PATH * sizeof(WCHAR));
  236. mediumUser.hGlobal = hMem;
  237. HRESULT hr = S_OK;
  238. DWORD dwError;
  239. LPWSTR pMachineName = NULL;
  240. LPWSTR pUserName = NULL;
  241. SERVER_INFO_102* pServerInfo102 = NULL;
  242. NET_API_STATUS netRet = 0;
  243. DSROLE_PRIMARY_DOMAIN_INFO_BASIC* pdsRole = NULL;
  244. //==================================================================
  245. // check if the machine is a standalone NT5 server
  246. // check if the machine focused on is NT5 machine
  247. if ( !g_cfMachineName )
  248. g_cfMachineName = RegisterClipboardFormat(CCF_LOCAL_USER_MANAGER_MACHINE_NAME);
  249. fmte.cfFormat = g_cfMachineName;
  250. CHECK_HR( hr = pDataObject->GetDataHere(&fmte, &mediumMachine));
  251. pMachineName = (LPWSTR)mediumMachine.hGlobal;
  252. ASSERT(pMachineName);
  253. if(!pMachineName) CHECK_HR(hr = E_INVALIDARG);
  254. // not to show the page if focusing on workstation
  255. // TODO change to real
  256. /* postpone, till The dialog is being called
  257. if(HrIsNTServer(pMachineName) != S_OK)
  258. {
  259. m_bShowPage = FALSE;
  260. goto L_EXIT;
  261. }
  262. */
  263. if (g_cfDisplayName == 0)
  264. g_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  265. fmte.cfFormat = g_cfDisplayName;
  266. CHECK_HR( hr = pDataObject->GetDataHere(&fmte, &mediumUser));
  267. pUserName = (LPWSTR)mediumUser.hGlobal;
  268. ASSERT(pUserName);
  269. if(!pUserName)
  270. CHECK_HR(hr = E_INVALIDARG);
  271. ASSERT(!m_pMergedPage);
  272. try{
  273. m_pMergedPage = new CDlgRASDialinMerge(RASUSER_ENV_LOCAL, pMachineName, pUserName);
  274. #ifdef SINGLE_SDO_CONNECTION // for share the same sdo connection for multiple users
  275. CHECK_HR(hr = GetSharedSdoServer(pMachineName, NULL, NULL, NULL, m_pMergedPage->GetMarshalSdoServerHolder()));
  276. #endif
  277. // tell MMC to hook the proc because we are running on a separate,
  278. // non MFC thread.
  279. m_pMergedPage->m_psp.pfnCallback = &CDlgRASDialinMerge::PropSheetPageProc;
  280. // We also need to save a self-reference so that the static callback
  281. // function can recover a "this" pointer
  282. m_pMergedPage->m_psp.lParam = (LONG_PTR)m_pMergedPage;
  283. MMCPropPageCallback(&m_pMergedPage->m_psp);
  284. HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(&m_pMergedPage->m_psp);
  285. if(hPage == NULL)
  286. return E_UNEXPECTED;
  287. lpProvider->AddPage(hPage);
  288. }catch(CMemoryException&){
  289. delete m_pMergedPage;
  290. m_pMergedPage = NULL;
  291. CHECK_HR(hr = E_OUTOFMEMORY);
  292. }
  293. L_ERR:
  294. if FAILED(hr)
  295. ReportError(hr, IDS_ERR_PROPERTYPAGE, NULL);
  296. if(pUserName)
  297. GlobalFree(pUserName);
  298. if(pMachineName)
  299. GlobalFree(pMachineName);
  300. if(pServerInfo102)
  301. NetApiBufferFree(pServerInfo102);
  302. return hr;
  303. }