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.

375 lines
11 KiB

  1. /*++
  2. Module Name:
  3. IPStream.cpp
  4. Abstract:
  5. This module contains the implementation for CDfsSnapinScopeManager.
  6. This class implements IPersistStream interface for the above.
  7. --*/
  8. #include "stdafx.h"
  9. #include "DfsGUI.h"
  10. #include "DfsScope.h"
  11. #include "utils.h"
  12. #include <lmdfs.h>
  13. STDMETHODIMP
  14. CDfsSnapinScopeManager::GetClassID(
  15. OUT struct _GUID* o_pClsid
  16. )
  17. /*++
  18. Routine Description:
  19. Return the snapin CLSID.
  20. Arguments:
  21. o_pClsid - The clsid is returned here.
  22. --*/
  23. {
  24. *o_pClsid = CLSID_DfsSnapinScopeManager;
  25. return S_OK;
  26. }
  27. STDMETHODIMP
  28. CDfsSnapinScopeManager::IsDirty(
  29. )
  30. /*++
  31. Routine Description:
  32. Use to check if the object has been changed since last save.
  33. Returns S_OK if it has, otherwise returns S_FALSE
  34. Return value:
  35. S_OK, if the object has changed. i.e., dirty
  36. S_FALSE, if the object has not changed, i.e., not dirty.
  37. --*/
  38. {
  39. return m_pMmcDfsAdmin->GetDirty() ? S_OK : S_FALSE;
  40. }
  41. STDMETHODIMP
  42. CDfsSnapinScopeManager::Load(
  43. IN LPSTREAM i_pStream
  44. )
  45. /*++
  46. Routine Description:
  47. Used to load the snap-in from a saved file(.MSC file).
  48. We set dirty to false(to disbale save), if load succeeds completely
  49. Arguments:
  50. i_pStream - Pointer to an IPersistStream object from which the saved information is to
  51. be read.
  52. --*/
  53. {
  54. RETURN_INVALIDARG_IF_NULL(i_pStream);
  55. CWaitCursor WaitCursor;
  56. // Get the size of data that was stored
  57. ULONG ulDataLen = 0;
  58. ULONG uBytesRead = 0;
  59. HRESULT hr = i_pStream->Read(&ulDataLen, sizeof (ULONG), &uBytesRead);
  60. RETURN_IF_FAILED(hr);
  61. if (ulDataLen <= 0) // No use in continuing if no data is there
  62. {
  63. // do we have a local dfsroot?
  64. TCHAR szLocalComputerName[MAX_COMPUTERNAME_LENGTH + 1] = {0};
  65. DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  66. GetComputerName(szLocalComputerName, &dwSize);
  67. NETNAMELIST DfsRootList;
  68. if (S_OK == GetDomainDfsRoots(&DfsRootList, szLocalComputerName) && !DfsRootList.empty())
  69. {
  70. for (NETNAMELIST::iterator i = DfsRootList.begin(); i != DfsRootList.end(); i++)
  71. {
  72. CComBSTR bstrRootEntryPath = _T("\\\\");
  73. bstrRootEntryPath += szLocalComputerName;
  74. bstrRootEntryPath += _T("\\");
  75. bstrRootEntryPath += (*i)->bstrNetName;
  76. CComPtr<IDfsRoot> pDfsRoot;
  77. hr = CoCreateInstance(CLSID_DfsRoot, NULL, CLSCTX_INPROC_SERVER, IID_IDfsRoot, (void**) &pDfsRoot);
  78. if(SUCCEEDED(hr))
  79. {
  80. hr = pDfsRoot->Initialize(bstrRootEntryPath);
  81. if (S_OK == hr)
  82. (void)m_pMmcDfsAdmin->AddDfsRootToList(pDfsRoot);
  83. }
  84. }
  85. }
  86. /*
  87. CComBSTR bstrRootEntryPath;
  88. hr = IsHostingDfsRoot(szLocalComputerName, &bstrRootEntryPath);
  89. if (S_OK == hr)
  90. {
  91. CComPtr<IDfsRoot> pDfsRoot;
  92. hr = CoCreateInstance (CLSID_DfsRoot, NULL, CLSCTX_INPROC_SERVER, IID_IDfsRoot, (void**) &pDfsRoot);
  93. if(SUCCEEDED(hr))
  94. {
  95. hr = pDfsRoot->Initialize(bstrRootEntryPath);
  96. if (S_OK == hr)
  97. (void)m_pMmcDfsAdmin->AddDfsRootToList(pDfsRoot);
  98. }
  99. } */
  100. } else
  101. {
  102. bool bSomeLoadFailed = false;
  103. BYTE* pStreamData = NULL;
  104. do {
  105. pStreamData = new BYTE [ulDataLen]; // Allocate memory for the data to be read
  106. BREAK_OUTOFMEMORY_IF_NULL(pStreamData, &hr);
  107. // Read the data from the stream
  108. hr = i_pStream->Read(pStreamData, ulDataLen, &uBytesRead);
  109. BREAK_IF_FAILED(hr);
  110. BYTE* pData = pStreamData;
  111. BYTE* pDataEnd = pStreamData + ulDataLen;
  112. // Start by reading the first machines name
  113. ULONG nVersion = 0;
  114. TCHAR *lpszDfsName = (LPTSTR)pData;
  115. if (*lpszDfsName == _T('\\'))
  116. {
  117. nVersion = 0;
  118. } else
  119. {
  120. ULONG* pVer = (ULONG*)pData;
  121. if (*pVer == 1)
  122. {
  123. nVersion = 1;
  124. pData += sizeof(ULONG);
  125. } else
  126. {
  127. hr = S_FALSE; // corrupted console file
  128. break;
  129. }
  130. }
  131. do
  132. {
  133. lpszDfsName = (LPTSTR)pData;
  134. pData += sizeof(TCHAR) * (_tcslen(lpszDfsName) + 1);
  135. CComPtr<IDfsRoot> pDfsRoot;
  136. hr = CoCreateInstance (CLSID_DfsRoot, NULL, CLSCTX_INPROC_SERVER, IID_IDfsRoot, (void**) &pDfsRoot);
  137. BREAK_IF_FAILED(hr);
  138. // retrieve link filtering settings
  139. ULONG ulMaxLimit = FILTERDFSLINKS_MAXLIMIT_DEFAULT;
  140. FILTERDFSLINKS_TYPE lFilterType = FILTERDFSLINKS_TYPE_NO_FILTER;
  141. TCHAR *pszFilterName = NULL;
  142. if (nVersion == 1)
  143. {
  144. ulMaxLimit = *((ULONG *)pData);
  145. pData += sizeof(ULONG);
  146. lFilterType = *((enum FILTERDFSLINKS_TYPE *)pData);
  147. pData += sizeof(lFilterType);
  148. if (lFilterType != FILTERDFSLINKS_TYPE_NO_FILTER)
  149. {
  150. pszFilterName = (LPTSTR)pData;
  151. pData += sizeof(TCHAR) * (_tcslen(pszFilterName) + 1);
  152. }
  153. }
  154. hr = pDfsRoot->Initialize(lpszDfsName);
  155. if (S_OK == hr)
  156. {
  157. CComBSTR bstrDfsRootEntryPath;
  158. hr = pDfsRoot->get_RootEntryPath(&bstrDfsRootEntryPath);
  159. if (SUCCEEDED(hr))
  160. {
  161. // If already present in the list, just ignore this entry
  162. hr = m_pMmcDfsAdmin->IsAlreadyInList(bstrDfsRootEntryPath);
  163. if (S_OK != hr)
  164. {
  165. (void) m_pMmcDfsAdmin->AddDfsRootToList(
  166. pDfsRoot, ulMaxLimit, lFilterType, pszFilterName);
  167. }
  168. }
  169. }
  170. else
  171. {
  172. DisplayMessageBoxWithOK(IDS_MSG_FAILED_TO_INITIALIZE_DFSROOT, lpszDfsName);
  173. bSomeLoadFailed = true; // Since we could not create a dfsroot
  174. }
  175. } while (pData < pDataEnd);
  176. } while (false);
  177. if (pStreamData)
  178. delete [] pStreamData;
  179. m_pMmcDfsAdmin->SetDirty(bSomeLoadFailed); // Cause we just read the whole dfsroot list from file
  180. }
  181. return hr;
  182. }
  183. STDMETHODIMP
  184. CDfsSnapinScopeManager::Save(
  185. OUT LPSTREAM o_pStream,
  186. IN BOOL i_bClearDirty
  187. )
  188. /*++
  189. Routine Description:
  190. Used to save the snap-in to a .MSC file. This uses a IPersistStream object.
  191. Arguments:
  192. o_pStream - Pointer to an IPersistStream object to which the saved information is to
  193. be written.
  194. i_bClearDirty - A flag indication whether the dirty flag should be cleared
  195. --*/
  196. {
  197. RETURN_INVALIDARG_IF_NULL(o_pStream);
  198. ULONG nVersion = 1;
  199. DFS_ROOT_LIST* lpDfsRootList = NULL;
  200. HRESULT hr = m_pMmcDfsAdmin->GetList (&lpDfsRootList);
  201. RETURN_IF_FAILED(hr);
  202. ULONG ulDataLen = 0;
  203. DFS_ROOT_LIST::iterator i;
  204. for (i = lpDfsRootList->begin(); i != lpDfsRootList->end(); i++)
  205. {
  206. ulDataLen +=
  207. ((_tcslen((*i)->m_bstrRootEntryPath) + 1) * sizeof (TCHAR)) + // to hold RootEntryPath
  208. sizeof(ULONG) + // to hold LinkFilterMaxLimit
  209. sizeof(enum FILTERDFSLINKS_TYPE); // to hold LinkFilterType
  210. if ((*i)->m_pMmcDfsRoot->get_LinkFilterType() != FILTERDFSLINKS_TYPE_NO_FILTER)
  211. {
  212. BSTR bstr = (*i)->m_pMmcDfsRoot->get_LinkFilterName();
  213. ulDataLen += ((bstr ? _tcslen(bstr) : 0) + 1) * sizeof(TCHAR); // to hold LinkFilterName
  214. }
  215. }
  216. if (!ulDataLen)
  217. return hr; // no root to presist, return
  218. ulDataLen += sizeof(nVersion); // to hold the version number
  219. // Allocate data
  220. BYTE* pStreamData = new BYTE [ulDataLen];
  221. RETURN_OUTOFMEMORY_IF_NULL(pStreamData);
  222. // Prepare the data
  223. BYTE* pData = pStreamData;
  224. ZeroMemory(pStreamData, ulDataLen);
  225. // hold version number
  226. memcpy(pData, &nVersion, sizeof(nVersion));
  227. pData += sizeof(nVersion);
  228. int len = 0;
  229. for (i = lpDfsRootList->begin(); i != lpDfsRootList->end(); i++)
  230. {
  231. // hold RootEntryPath
  232. len = (_tcslen((*i)->m_bstrRootEntryPath) + 1) * sizeof(TCHAR);
  233. memcpy(pData, (*i)->m_bstrRootEntryPath, len);
  234. pData += len;
  235. // hold LinkFilterMaxLimit
  236. ULONG ulLinkFilterMaxLimit = (*i)->m_pMmcDfsRoot->get_LinkFilterMaxLimit();
  237. memcpy(pData, &ulLinkFilterMaxLimit, sizeof(ulLinkFilterMaxLimit));
  238. pData += sizeof(ulLinkFilterMaxLimit);
  239. // hold LinkFilterType
  240. FILTERDFSLINKS_TYPE lLinkFilterType = (*i)->m_pMmcDfsRoot->get_LinkFilterType();
  241. memcpy(pData, &lLinkFilterType, sizeof(lLinkFilterType));
  242. pData += sizeof(lLinkFilterType);
  243. // hold LinkFilterName
  244. if (lLinkFilterType != FILTERDFSLINKS_TYPE_NO_FILTER)
  245. {
  246. BSTR bstr = (*i)->m_pMmcDfsRoot->get_LinkFilterName();
  247. len = ((bstr ? _tcslen(bstr) : 0) + 1) * sizeof(TCHAR);
  248. memcpy(pData, (bstr ? bstr : _T("")), len);
  249. pData += len;
  250. }
  251. }
  252. // Write the data length to the stream
  253. ULONG uBytesWritten = 0;
  254. hr = o_pStream->Write(&ulDataLen, sizeof(ulDataLen), &uBytesWritten);
  255. if(SUCCEEDED(hr))
  256. {
  257. // Now write the data to the stream
  258. hr = o_pStream->Write(pStreamData, ulDataLen, &uBytesWritten);
  259. }
  260. if (pStreamData)
  261. delete [] pStreamData;
  262. if (i_bClearDirty)
  263. m_pMmcDfsAdmin->SetDirty(false);
  264. return hr;
  265. }
  266. STDMETHODIMP
  267. CDfsSnapinScopeManager::GetSizeMax(
  268. OUT ULARGE_INTEGER* o_pulSize
  269. )
  270. /*++
  271. Routine Description:
  272. Return the size of the data we will write to the stream.
  273. Arguments:
  274. o_ulcbSize - Return the size of data in the low byte of this variable
  275. --*/
  276. {
  277. RETURN_INVALIDARG_IF_NULL(o_pulSize);
  278. DFS_ROOT_LIST* lpDfsRootList = NULL;
  279. HRESULT hr = m_pMmcDfsAdmin->GetList (&lpDfsRootList);
  280. RETURN_IF_FAILED(hr);
  281. ULONG ulDataLen = 0;
  282. for (DFS_ROOT_LIST::iterator i = lpDfsRootList->begin(); i != lpDfsRootList->end(); i++)
  283. {
  284. ulDataLen += (_tcslen ((*i)->m_bstrRootEntryPath) + 1) * sizeof (TCHAR);
  285. }
  286. o_pulSize->LowPart = ulDataLen; // Return the size in the low bit
  287. o_pulSize->HighPart = 0;
  288. return hr;
  289. }