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.

429 lines
10 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. logfile.cpp
  5. Abstract:
  6. This file contains the implementation of the ValidateLogFile() function,
  7. which reads and validate restore operations log file.
  8. Revision History:
  9. Seong Kook Khang (SKKhang) 08/20/99
  10. created
  11. ******************************************************************************/
  12. #include "stdwin.h"
  13. #include "rstrpriv.h"
  14. #include "srui_htm.h"
  15. #include "rstrmgr.h"
  16. #include "srapi.h"
  17. static LPCWSTR s_cszLogPath = L"%SystemRoot%\\system32\\restore\\rstrlog.dat";
  18. static LPCWSTR s_cszWinInitErr = L"%SystemRoot%\\wininit.err";
  19. /******************************************************************************/
  20. BOOL ReadStrAlign4( HANDLE hFile, LPWSTR pszStr )
  21. {
  22. BOOL fRet = FALSE;
  23. DWORD dwLen;
  24. DWORD dwRead;
  25. if ( !::ReadFile( hFile, &dwLen, sizeof(DWORD), &dwRead, NULL ) || dwRead != sizeof(DWORD) )
  26. {
  27. goto Exit;
  28. }
  29. if ( dwRead > MAX_PATH+4 )
  30. {
  31. // Broken log file...
  32. goto Exit;
  33. }
  34. if ( dwLen > 0 )
  35. {
  36. if ( !::ReadFile( hFile, pszStr, dwLen, &dwRead, NULL ) || dwRead != dwLen )
  37. {
  38. goto Exit;
  39. }
  40. }
  41. fRet = TRUE;
  42. Exit:
  43. return( fRet );
  44. }
  45. /////////////////////////////////////////////////////////////////////////////
  46. //
  47. // CMappedFileRead class
  48. //
  49. /////////////////////////////////////////////////////////////////////////////
  50. class CMappedFileRead
  51. {
  52. public:
  53. CMappedFileRead();
  54. ~CMappedFileRead();
  55. // Operations
  56. public:
  57. void Close();
  58. BOOL Open( LPCWSTR cszPath );
  59. BOOL Read( LPVOID pBuf, DWORD cbBuf );
  60. BOOL Read( DWORD *pdw );
  61. BOOL ReadDynStr( LPWSTR szBuf, DWORD cchMax );
  62. protected:
  63. // Attributes
  64. public:
  65. DWORD GetAvail() { return( m_dwAvail ); }
  66. protected:
  67. WCHAR m_szPath[MAX_PATH];
  68. DWORD m_dwSize;
  69. HANDLE m_hFile;
  70. HANDLE m_hMap;
  71. LPBYTE m_pBuf;
  72. LPBYTE m_pCur;
  73. DWORD m_dwAvail;
  74. };
  75. /////////////////////////////////////////////////////////////////////////////
  76. // CMappedFileRead construction / destruction
  77. CMappedFileRead::CMappedFileRead()
  78. {
  79. m_szPath[0] = L'\0';
  80. m_dwSize = 0;
  81. m_hFile = INVALID_HANDLE_VALUE;
  82. m_hMap = INVALID_HANDLE_VALUE;
  83. m_pBuf = NULL;
  84. }
  85. CMappedFileRead::~CMappedFileRead()
  86. {
  87. Close();
  88. }
  89. /////////////////////////////////////////////////////////////////////////////
  90. // CMappedFileRead operations
  91. void CMappedFileRead::Close()
  92. {
  93. TraceFunctEnter("CMappedFileRead::Close");
  94. if ( m_pBuf != NULL )
  95. {
  96. ::UnmapViewOfFile( m_pBuf );
  97. m_pBuf = NULL;
  98. }
  99. if ( m_hMap != INVALID_HANDLE_VALUE )
  100. {
  101. ::CloseHandle( m_hMap );
  102. m_hMap = INVALID_HANDLE_VALUE;
  103. }
  104. if ( m_hFile != INVALID_HANDLE_VALUE )
  105. {
  106. ::CloseHandle( m_hFile );
  107. m_hFile = INVALID_HANDLE_VALUE;
  108. }
  109. TraceFunctLeave();
  110. }
  111. /////////////////////////////////////////////////////////////////////////////
  112. BOOL CMappedFileRead::Open( LPCWSTR cszPath )
  113. {
  114. TraceFunctEnter("CMappedFileRead::Open");
  115. BOOL fRet = FALSE;
  116. LPCWSTR cszErr;
  117. Close();
  118. m_hFile = ::CreateFile( cszPath, GENERIC_READ,
  119. FILE_SHARE_READ|FILE_SHARE_WRITE,
  120. NULL, OPEN_EXISTING, 0, NULL );
  121. if ( m_hFile == INVALID_HANDLE_VALUE )
  122. {
  123. cszErr = ::GetSysErrStr();
  124. ErrorTrace(0, "::CreateFile failed - %ls", cszErr);
  125. goto Exit;
  126. }
  127. m_dwSize = ::GetFileSize( m_hFile, NULL );
  128. if ( m_dwSize == 0xFFFFFFFF )
  129. {
  130. cszErr = ::GetSysErrStr();
  131. ErrorTrace(0, "::GetFileSize failed - %ls", cszErr);
  132. goto Exit;
  133. }
  134. m_hMap = ::CreateFileMapping( m_hFile, NULL, PAGE_READONLY, 0, 0, NULL );
  135. if ( m_hFile == INVALID_HANDLE_VALUE )
  136. {
  137. cszErr = ::GetSysErrStr();
  138. ErrorTrace(0, "::CreateFileMapping failed - %ls", cszErr);
  139. goto Exit;
  140. }
  141. m_pBuf = (LPBYTE)::MapViewOfFile( m_hMap, FILE_MAP_READ, 0, 0, 0 );
  142. if ( m_pBuf == NULL )
  143. {
  144. cszErr = ::GetSysErrStr();
  145. ErrorTrace(0, "::MapViewOfFile failed - %ls", cszErr);
  146. goto Exit;
  147. }
  148. ::lstrcpy( m_szPath, cszPath );
  149. m_pCur = m_pBuf;
  150. m_dwAvail = m_dwSize;
  151. fRet = TRUE;
  152. Exit:
  153. if ( !fRet )
  154. Close();
  155. TraceFunctLeave();
  156. return( fRet );
  157. }
  158. /////////////////////////////////////////////////////////////////////////////
  159. BOOL CMappedFileRead::Read( LPVOID pBuf, DWORD cbBuf )
  160. {
  161. TraceFunctEnter("CMappedFileRead::Read(LPVOID,DWORD)");
  162. BOOL fRet = FALSE;
  163. if ( cbBuf > m_dwAvail )
  164. {
  165. ErrorTrace(0, "Insufficient data - %d bytes (need=%d bytes)\n", m_dwAvail, cbBuf);
  166. goto Exit;
  167. }
  168. ::CopyMemory( pBuf, m_pCur, cbBuf );
  169. m_pCur += cbBuf;
  170. m_dwAvail -= cbBuf;
  171. fRet = TRUE;
  172. Exit:
  173. TraceFunctLeave();
  174. return( fRet );
  175. }
  176. /////////////////////////////////////////////////////////////////////////////
  177. BOOL CMappedFileRead::Read( DWORD *pdw )
  178. {
  179. TraceFunctEnter("CMappedFileRead::Read(DWORD*)");
  180. BOOL fRet = FALSE;
  181. if ( sizeof(DWORD) > m_dwAvail )
  182. {
  183. ErrorTrace(0, "Insufficient data - %d bytes (need=%d bytes)\n", m_dwAvail, sizeof(DWORD));
  184. goto Exit;
  185. }
  186. *pdw = *((LPDWORD)m_pCur);
  187. m_pCur += sizeof(DWORD);
  188. m_dwAvail -= sizeof(DWORD);
  189. fRet = TRUE;
  190. Exit:
  191. TraceFunctLeave();
  192. return( fRet );
  193. }
  194. /////////////////////////////////////////////////////////////////////////////
  195. BOOL CMappedFileRead::ReadDynStr( LPWSTR szBuf, DWORD cchMax )
  196. {
  197. TraceFunctEnter("CMappedFileRead::Read(LPWSTR,DWORD)");
  198. BOOL fRet = FALSE;
  199. DWORD dwLen;
  200. // note, this "length" is in bytes, not chars.
  201. if ( !Read( &dwLen ) )
  202. goto Exit;
  203. if ( dwLen == 0 )
  204. {
  205. szBuf[0] = L'\0';
  206. goto Done;
  207. }
  208. if ( dwLen > cchMax*sizeof(WCHAR) )
  209. {
  210. ErrorTrace(0, "Invalid string length - %d (max=%d)\n", dwLen, cchMax);
  211. goto Exit;
  212. }
  213. if ( !Read( szBuf, dwLen ) )
  214. goto Exit;
  215. Done:
  216. fRet = TRUE;
  217. Exit:
  218. TraceFunctLeave();
  219. return( fRet );
  220. }
  221. /////////////////////////////////////////////////////////////////////////////
  222. //
  223. // ValidateLogFile function
  224. //
  225. /////////////////////////////////////////////////////////////////////////////
  226. struct SRFINode
  227. {
  228. PSRFI pRFI;
  229. SRFINode *pNext;
  230. };
  231. BOOL ValidateLogFile( BOOL *pfSilent, BOOL *pfUndo )
  232. {
  233. TraceFunctEnter("ValidateLogFile");
  234. BOOL fRet = FALSE;
  235. WCHAR szLogPath[MAX_PATH];
  236. CMappedFileRead cMFR;
  237. SRstrLogHdrBase sHdr1;
  238. SRstrLogHdrV3 sHdr2;
  239. SRstrLogHdrV3Ex sHdr3;
  240. SRstrEntryHdr sEntHdr;
  241. DWORD i;
  242. DWORD dwFlags;
  243. WCHAR szBuf1[SR_MAX_FILENAME_LENGTH];
  244. WCHAR szBuf2[SR_MAX_FILENAME_LENGTH];
  245. WCHAR szBuf3[SR_MAX_FILENAME_LENGTH];
  246. PSRFI pRFI;
  247. ::ExpandEnvironmentStrings( s_cszLogPath, szLogPath, MAX_PATH );
  248. if ( !cMFR.Open( szLogPath ) )
  249. goto Exit;
  250. if ( !cMFR.Read( &sHdr1, sizeof(sHdr1) ) )
  251. goto Exit;
  252. if ( ( sHdr1.dwSig1 != RSTRLOG_SIGNATURE1 ) ||
  253. ( sHdr1.dwSig2 != RSTRLOG_SIGNATURE2 ) )
  254. {
  255. ErrorTrace(0, "Invalid restore log file signature...");
  256. goto Exit;
  257. }
  258. if ( HIWORD(sHdr1.dwVer) != RSTRLOG_VER_MAJOR )
  259. {
  260. ErrorTrace(0, "Unknown restore log file version - %d (0x%08X)\n", HIWORD(sHdr1.dwVer), sHdr1.dwVer);
  261. goto Exit;
  262. }
  263. if ( !cMFR.Read( &sHdr2, sizeof(sHdr2) ) )
  264. goto Exit;
  265. if ( pfSilent != NULL )
  266. *pfSilent = ( ( sHdr2.dwFlags & RLHF_SILENT ) != 0 );
  267. if ( pfUndo != NULL )
  268. *pfUndo = ( ( sHdr2.dwFlags & RLHF_UNDO ) != 0 );
  269. g_pRstrMgr->SetRPsUsed( sHdr2.dwRPNum, sHdr2.dwRPNew );
  270. DebugTrace(0, "RP ID = %d, # of Drives = %d, New RP=%d", sHdr2.dwRPNum, sHdr2.dwDrives, sHdr2.dwRPNew);
  271. for ( i = 0; i < sHdr2.dwDrives; i++ )
  272. {
  273. if ( !cMFR.Read( &dwFlags ) )
  274. goto Exit;
  275. if ( !cMFR.ReadDynStr( szBuf1, MAX_PATH ) )
  276. goto Exit;
  277. if ( !cMFR.ReadDynStr( szBuf2, MAX_PATH ) )
  278. goto Exit;
  279. if ( !cMFR.ReadDynStr( szBuf3, MAX_PATH ) )
  280. goto Exit;
  281. DebugTrace(0, "Drv#%d - %08X, %ls, %ls, %ls", i, dwFlags, szBuf1, szBuf2, szBuf3);
  282. // Just ignore drive table...
  283. }
  284. //if ( !cMFR.Read( &sHdr3, sizeof(sHdr3) ) )
  285. // goto Exit;
  286. //DebugTrace(0, "New RP ID = %d, # of Entries = %d", sHdr3.dwRPNew, sHdr3.dwCount);
  287. for ( i = 0; cMFR.GetAvail() > 0; i++ )
  288. {
  289. if ( !cMFR.Read( &sEntHdr, sizeof(sEntHdr) ) )
  290. goto Exit;
  291. if ( sEntHdr.dwRes == RSTRRES_FAIL )
  292. goto Exit;
  293. if ( ( sEntHdr.dwID == RSTRLOGID_STARTUNDO ) ||
  294. ( sEntHdr.dwID == RSTRLOGID_ENDOFUNDO ) )
  295. continue;
  296. if ( sEntHdr.dwID == RSTRLOGID_ENDOFMAP )
  297. {
  298. if ( cMFR.GetAvail() > 0 )
  299. {
  300. ErrorTrace(0, "Unknown trailing data after the EndOfMap marker...");
  301. // but ignore and continue...
  302. }
  303. break;
  304. }
  305. if ( !cMFR.ReadDynStr( szBuf1, SR_MAX_FILENAME_LENGTH ) )
  306. goto Exit;
  307. if ( !cMFR.ReadDynStr( szBuf2, SR_MAX_FILENAME_LENGTH ) )
  308. goto Exit;
  309. if ( !cMFR.ReadDynStr( szBuf3, SR_MAX_FILENAME_LENGTH ) )
  310. goto Exit;
  311. if ( sEntHdr.dwID == RSTRLOGID_COLLISION )
  312. {
  313. pRFI = new SRenamedFolderInfo;
  314. if ( pRFI == NULL )
  315. {
  316. FatalTrace(0, "Insufficient memory...");
  317. goto Exit;
  318. }
  319. pRFI->strOld = ::PathFindFileName( szBuf1 );
  320. pRFI->strNew = ::PathFindFileName( szBuf2 );
  321. ::PathRemoveFileSpec( szBuf2 );
  322. pRFI->strLoc = szBuf2;
  323. if ( !g_pRstrMgr->AddRenamedFolder( pRFI ) )
  324. goto Exit;
  325. }
  326. }
  327. fRet = TRUE;
  328. Exit:
  329. cMFR.Close();
  330. TraceFunctLeave();
  331. return( fRet );
  332. }
  333. /******************************************************************************/
  334. BOOL CheckWininitErr()
  335. {
  336. TraceFunctEnter("CheckWininitErr");
  337. BOOL fRet = FALSE;
  338. WCHAR szWinInitErr[MAX_PATH+1];
  339. ::ExpandEnvironmentStrings( s_cszWinInitErr, szWinInitErr, MAX_PATH );
  340. if ( ::GetFileAttributes( szWinInitErr ) != 0xFFFFFFFF )
  341. {
  342. DebugTrace(TRACE_ID, "WININIT.ERR file exists");
  343. goto Exit;
  344. }
  345. fRet = TRUE;
  346. Exit:
  347. TraceFunctLeave();
  348. return( fRet );
  349. }
  350. // end of file