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.

474 lines
10 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved.
  3. Module Name:
  4. RsClnSrv.cpp
  5. Abstract:
  6. Implementation of CRsClnServer. This class represents a Remote
  7. Storage server whose local volumes are to be scanned for Remote
  8. Storage data and possibly cleaned. Cleaning means removing all
  9. Remote Storage reparse points truncated files from all local fixed
  10. disk volumes. CRsClnServer creates one or more instances of
  11. CRsClnVolume.
  12. Author:
  13. Carl Hagerstrom [carlh] 20-Aug-1998
  14. Revision History:
  15. --*/
  16. #include <stdafx.h>
  17. #include <ntseapi.h>
  18. /*++
  19. Implements:
  20. CRsClnServer Constructor
  21. Routine Description:
  22. Initializes list of volumes containing Remote Storage data.
  23. --*/
  24. CRsClnServer::CRsClnServer()
  25. {
  26. TRACEFN("CRsClnServer::CRsClnServer");
  27. m_head = (struct dirtyVolume*)0;
  28. m_tail = (struct dirtyVolume*)0;
  29. m_current = (struct dirtyVolume*)0;
  30. }
  31. /*++
  32. Implements:
  33. CRsClnServer Destructor
  34. Routine Description:
  35. Cleans up memory used by list of volumes containging Remote
  36. Storage data.
  37. --*/
  38. CRsClnServer::~CRsClnServer()
  39. {
  40. TRACEFN("CRsClnServer::~CRsClnServer");
  41. RemoveDirtyVolumes();
  42. }
  43. /*++
  44. Implements:
  45. CRsClnServer::ScanServer
  46. Routine Description:
  47. Scans this server for volumes containing Remote Storage data.
  48. If so, the sticky name and a user friendly name is added to
  49. a list of such volumes.
  50. Arguments:
  51. volCount - returned: number of volumes containing Remote
  52. Storage data
  53. Return Value:
  54. S_OK - Success
  55. HRESULT - Any unexpected exceptions from lower level routines
  56. --*/
  57. HRESULT CRsClnServer::ScanServer(DWORD *volCount)
  58. {
  59. TRACEFNHR("CRsClnServer::ScanServer");
  60. WCHAR stickyName[MAX_STICKY_NAME];
  61. HANDLE hScan = INVALID_HANDLE_VALUE;
  62. BOOL hasData;
  63. *volCount = 0;
  64. try {
  65. for( BOOL firstLoop = TRUE;; firstLoop = FALSE ) {
  66. if( firstLoop ) {
  67. hScan = FindFirstVolume(stickyName, (sizeof(stickyName) / sizeof(stickyName[0])) );
  68. RsOptAffirmHandle(hScan);
  69. } else {
  70. if( !FindNextVolume(hScan, stickyName, (sizeof(stickyName) / sizeof(stickyName[0])) ) ) {
  71. break;
  72. }
  73. }
  74. CRsClnVolume volObj( this, stickyName );
  75. RsOptAffirmDw( volObj.VolumeHasRsData( &hasData ) );
  76. if( hasData ) {
  77. RsOptAffirmDw( AddDirtyVolume( stickyName, (LPTSTR)(LPCTSTR)volObj.GetBestName( ) ) );
  78. ++(*volCount);
  79. }
  80. }
  81. }
  82. RsOptCatch( hrRet );
  83. if (INVALID_HANDLE_VALUE != hScan) {
  84. FindVolumeClose( hScan );
  85. }
  86. return( hrRet );
  87. }
  88. /*++
  89. Implements:
  90. CRsClnServer::FirstDirtyVolume
  91. Routine Description:
  92. Return the name of the first volume on this server
  93. containing Remote Storage data.
  94. Arguments:
  95. bestName - returned: user friendly volume name if one exists
  96. or the sticky name
  97. Return Value:
  98. S_OK - Success
  99. HRESULT - Any unexpected exceptions from lower level routines
  100. --*/
  101. HRESULT CRsClnServer::FirstDirtyVolume(WCHAR** bestName)
  102. {
  103. TRACEFNHR("CRsClnServer::FirstDirtyVolume");
  104. *bestName = (WCHAR*)0;
  105. m_current = m_head;
  106. if (m_current)
  107. {
  108. *bestName = m_current->bestName;
  109. }
  110. return hrRet;
  111. }
  112. /*++
  113. Implements:
  114. CRsClnServer::NextDirtyVolume
  115. Routine Description:
  116. Return the name of the next volume on this server
  117. containing Remote Storage data.
  118. Arguments:
  119. bestName - returned: user friendly volume name if one exists
  120. or the sticky name
  121. Return Value:
  122. S_OK - Success
  123. HRESULT - Any unexpected exceptions from lower level routines
  124. --*/
  125. HRESULT CRsClnServer::NextDirtyVolume(WCHAR** bestName)
  126. {
  127. TRACEFNHR("CRsClnServer::NextDirtyVolume");
  128. m_current = m_current->next;
  129. if( m_current ) {
  130. *bestName = m_current->bestName;
  131. } else {
  132. *bestName = (WCHAR*)0;
  133. }
  134. return( hrRet );
  135. }
  136. /*++
  137. Implements:
  138. CRsClnServer::RemoveDirtyVolumes()
  139. Routine Description:
  140. Cleans up memory used by list of volumes containging Remote
  141. Storage data.
  142. Return Value:
  143. S_OK - Success
  144. HRESULT - Any unexpected exceptions from lower level routines
  145. --*/
  146. HRESULT CRsClnServer::RemoveDirtyVolumes()
  147. {
  148. TRACEFNHR("CRsClnServer::RemoveDirtyVolumes");
  149. struct dirtyVolume* p;
  150. struct dirtyVolume* pnext;
  151. for( p = m_head; p; p = pnext ) {
  152. pnext = p->next;
  153. delete p;
  154. }
  155. m_head = (struct dirtyVolume*)0;
  156. m_tail = (struct dirtyVolume*)0;
  157. m_current = (struct dirtyVolume*)0;
  158. return( hrRet );
  159. }
  160. /*++
  161. Implements:
  162. CRsClnServer::CleanServer
  163. Routine Description:
  164. For each volume on this server which contains Remote Storage data,
  165. remove all the Remote Storage reparse points and any truncated files.
  166. Return Value:
  167. S_OK - Success
  168. HRESULT - Any unexpected exceptions from lower level routines
  169. --*/
  170. HRESULT CRsClnServer::CleanServer()
  171. {
  172. TRACEFNHR("CRsClnServer::CleanServer");
  173. HANDLE tokenHandle = 0;
  174. try {
  175. // Enable the backup operator privilege. This is required to insure that we
  176. // have full access to all resources on the system.
  177. TOKEN_PRIVILEGES newState;
  178. HANDLE pHandle;
  179. LUID backupValue;
  180. pHandle = GetCurrentProcess();
  181. RsOptAffirmStatus( OpenProcessToken( pHandle, MAXIMUM_ALLOWED, &tokenHandle ) );
  182. // adjust backup token privileges
  183. RsOptAffirmStatus( LookupPrivilegeValueW( NULL, L"SeBackupPrivilege", &backupValue ) );
  184. newState.PrivilegeCount = 1;
  185. newState.Privileges[0].Luid = backupValue;
  186. newState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  187. RsOptAffirmStatus( AdjustTokenPrivileges( tokenHandle, FALSE, &newState, (DWORD)0, NULL, NULL ) );
  188. // Do the cleaning
  189. for( m_current = m_head; m_current; m_current = m_current->next ) {
  190. CRsClnVolume volObj( this, m_current->stickyName );
  191. RsOptAffirmDw( volObj.RemoveRsDataFromVolume( ) );
  192. }
  193. } RsOptCatch( hrRet );
  194. if( tokenHandle ) CloseHandle( tokenHandle );
  195. //
  196. // And if we had errors on a file,
  197. // show them up in a dialog
  198. //
  199. if( ! m_ErrorFileList.IsEmpty( ) ) {
  200. CRsClnErrorFiles dialog( &m_ErrorFileList );
  201. dialog.DoModal( );
  202. }
  203. return( hrRet );
  204. }
  205. /*++
  206. Implements:
  207. CRsClnServer::AddDirtyVolume
  208. Routine Description:
  209. Add the specified volume names to the list of volumes containing
  210. Remote Storage data.
  211. Arguments:
  212. stickyName - long volume name guaranteed to exist for every volume
  213. bestName - user friendly volume name or sticky name if there is
  214. no DOS drive letter or volume name
  215. Return Value:
  216. S_OK - Success
  217. E_* - Any unexpected exceptions from lower level routines
  218. --*/
  219. HRESULT CRsClnServer::AddDirtyVolume(WCHAR* stickyName, WCHAR* bestName)
  220. {
  221. TRACEFNHR("CRsClnServer::AddDirtyVolume");
  222. try {
  223. struct dirtyVolume* dv = new struct dirtyVolume;
  224. RsOptAffirmPointer(dv);
  225. wcscpy(dv->stickyName, stickyName);
  226. wcscpy(dv->bestName, bestName);
  227. dv->next = (struct dirtyVolume*)0;
  228. if (!m_head)
  229. {
  230. m_head = dv;
  231. }
  232. else
  233. {
  234. m_tail->next = dv;
  235. }
  236. m_tail = dv;
  237. } RsOptCatch( hrRet );
  238. return( hrRet );
  239. }
  240. /*++
  241. Implements:
  242. CRsClnServer::AddErrorFile
  243. Routine Description:
  244. Add the specified file name to the list of files that an error
  245. occurred on while trying to remove Remote Storage.
  246. Arguments:
  247. FileName - Name of file to be added to the list
  248. Return Value:
  249. S_OK - Success
  250. E_* - Any unexpected exceptions from lower level routines
  251. --*/
  252. HRESULT
  253. CRsClnServer::AddErrorFile(
  254. CString& FileName
  255. )
  256. {
  257. TRACEFNHR( "CRsClnServer::AddErrorFile" );
  258. TRACE( L"FileName = <%ls>", FileName );
  259. m_ErrorFileList.AddTail( FileName );
  260. return( hrRet );
  261. }
  262. /////////////////////////////////////////////////////////////////////////////
  263. // CRsClnErrorFiles dialog
  264. CRsClnErrorFiles::CRsClnErrorFiles(CRsStringList* pFileList)
  265. : CDialog(CRsClnErrorFiles::IDD)
  266. {
  267. //{{AFX_DATA_INIT(CRsClnErrorFiles)
  268. // NOTE: the ClassWizard will add member initialization here
  269. //}}AFX_DATA_INIT
  270. m_ErrorFileList.AddHead( pFileList );
  271. }
  272. void CRsClnErrorFiles::DoDataExchange(CDataExchange* pDX)
  273. {
  274. CDialog::DoDataExchange(pDX);
  275. //{{AFX_DATA_MAP(CRsClnErrorFiles)
  276. DDX_Control(pDX, IDC_FILELIST, m_FileList);
  277. //}}AFX_DATA_MAP
  278. }
  279. BEGIN_MESSAGE_MAP(CRsClnErrorFiles, CDialog)
  280. //{{AFX_MSG_MAP(CRsClnErrorFiles)
  281. //}}AFX_MSG_MAP
  282. END_MESSAGE_MAP()
  283. /////////////////////////////////////////////////////////////////////////////
  284. // CRsClnErrorFiles message handlers
  285. BOOL CRsClnErrorFiles::OnInitDialog()
  286. {
  287. CDialog::OnInitDialog();
  288. //
  289. // Need to iterate through the list, adding each element to the listbox
  290. // and looking for the widest string so that we can set the horizontal
  291. // extent
  292. //
  293. int maxWidth = 0;
  294. CClientDC DC( &m_FileList );
  295. CFont* pFont = m_FileList.GetFont( );
  296. CFont* pOldFont = DC.SelectObject( pFont );
  297. while( ! m_ErrorFileList.IsEmpty( ) ) {
  298. CString fileName = m_ErrorFileList.RemoveHead( );
  299. m_FileList.AddString( fileName );
  300. CSize extent = DC.GetTextExtent( fileName );
  301. if( extent.cx > maxWidth ) maxWidth = extent.cx;
  302. }
  303. DC.SelectObject( pOldFont );
  304. m_FileList.SetHorizontalExtent( maxWidth );
  305. return( TRUE );
  306. }