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.

1347 lines
30 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. sfcp.h
  5. Abstract:
  6. Implementation of protected DLLs.
  7. This works by caching a set of dlls in a system directory
  8. and then synchronizing the cache with the target file locations.
  9. The process is driven by a list of protected dlls which is retrieved from a
  10. dll at runtime. Each entry contains a full path to the target
  11. file.
  12. Author:
  13. Wesley Witt (wesw) 18-Dec-1998
  14. Revision History:
  15. Andrew Ritz (andrewr) 2-Jul-1999 : added comments
  16. --*/
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <ntsm.h>
  21. #include <ntlsa.h>
  22. #include <ntrpcp.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <nturtl.h>
  27. #include <windows.h>
  28. #include <setupapi.h>
  29. #include <spapip.h>
  30. #include <elfkrnl.h>
  31. #include <newexe.h>
  32. #include <wincrypt.h>
  33. #include <mscat.h>
  34. #include <softpub.h>
  35. #include <wintrust.h>
  36. #include <sfcapip.h>
  37. #include <sfcapi.h>
  38. #include "sxsapi.h"
  39. #include "resource.h"
  40. #include "btree.h"
  41. #include "msg.h"
  42. #include "sfcfiles.h"
  43. #pragma warning(3:4101) // Unreferenced local variable
  44. //
  45. // public definitions
  46. //
  47. #define SFC_SHOW_REGISTRY_DATA 1
  48. #define SFC_PROT_VERBOSE_DEBUG 1
  49. #define FILE_NOTIFY_FLAGS (FILE_NOTIFY_CHANGE_NAME | \
  50. FILE_NOTIFY_CHANGE_SIZE | \
  51. FILE_NOTIFY_CHANGE_LAST_WRITE | \
  52. FILE_NOTIFY_CHANGE_CREATION | \
  53. FILE_NOTIFY_CHANGE_STREAM_SIZE | \
  54. FILE_NOTIFY_CHANGE_STREAM_WRITE)
  55. #if DBG
  56. #define MYASSERT( exp ) \
  57. if (!(exp)) \
  58. RtlAssert( #exp, __FILE__, __LINE__, NULL )
  59. #else
  60. #define MYASSERT( exp )
  61. #endif // DBG
  62. //
  63. // this is a free space buffer of 150 MB
  64. //
  65. #define SFC_REQUIRED_FREE_SPACE (600)
  66. #define ONE_MEG (1024*1024)
  67. #define WATCH_BUFFER_SIZE 4096
  68. #define VALUE_BUFFER_SIZE (sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 256 * sizeof(WCHAR))
  69. #define SHARE_ALL (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)
  70. //
  71. // macros
  72. //
  73. #define SecToNano(_sec) (DWORDLONG)((_sec) * 1000 * 1000 * 10)
  74. #define MinToNano(_min) SecToNano((_min)*60)
  75. #define UnicodeChars(_var) (sizeof(_var)/sizeof(WCHAR))
  76. #define UnicodeLen(_var) (wcslen(_var)*sizeof(WCHAR))
  77. #define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof((arr)[0])) // count of elements in an array
  78. #define LODWORD(l) ((ULONG)((DWORD_PTR)(l) & 0xffffffff))
  79. #define HIDWORD(l) ((ULONG)((DWORD_PTR)(l) >> 32))
  80. #define MIN(_first,_second) ((_first < _second) ? _first : _second)
  81. #define HideWindow(_hwnd) SetWindowLong((_hwnd),GWL_STYLE,GetWindowLong((_hwnd),GWL_STYLE)&~WS_VISIBLE)
  82. #define FileNameOnMedia(_RegVal) ( _RegVal->OriginalFileName[0] \
  83. ? _RegVal->OriginalFileName \
  84. : _RegVal->SourceFileName.Buffer \
  85. ? _RegVal->SourceFileName.Buffer \
  86. : _RegVal->FileName.Buffer )
  87. #define SpecialFileNameOnMedia(_RegVal) ( _RegVal->SourceFileName.Buffer \
  88. ? _RegVal->SourceFileName.Buffer \
  89. : _RegVal->FileName.Buffer )
  90. #define TAGFILE(_si) ((_si->Flags & SI_FLAG_USEDRIVER_CACHE) ? _si->DriverCabName : _si->TagFile)
  91. #if defined(_AMD64_)
  92. #define PLATFORM_DIR L"\\amd64"
  93. #define PLATFORM_NAME L"amd64"
  94. #elif defined(_X86_)
  95. #define PLATFORM_NAME (IsNEC_98 ? L"nec98" : L"i386")
  96. #define PLATFORM_DIR (IsNEC_98 ? L"\\nec98" : L"\\i386")
  97. #elif defined(_IA64_)
  98. #define PLATFORM_DIR L"\\ia64"
  99. #define PLATFORM_NAME L"ia64"
  100. #endif
  101. #define SFC_INCLUDE_SUBDIRECTORY TRUE
  102. #define SFC_INCLUDE_ARCHSUBDIR TRUE
  103. #define SFC_DISABLE_QUIET 0xffffff9d // -99
  104. #define SFC_VRD_SIGNATURE 0x69696969 // signature value
  105. #define SFC_QUEUE_STALL 5 // in seconds
  106. #define SFC_QUEUE_WAIT 5 // in seconds
  107. #define PATH_INVALID 0
  108. #define PATH_LOCAL 1
  109. #define PATH_UNC 2
  110. #define PATH_NETWORK 3
  111. #define PATH_CDROM 4
  112. #define KernelDebuggerEnabled ((USER_SHARED_DATA->KdDebuggerEnabled&3)==3)
  113. #define WM_WFPENDDIALOG WM_APP+69
  114. void
  115. dprintf(
  116. IN ULONG Level,
  117. IN PCWSTR FileName,
  118. IN ULONG LineNumber,
  119. IN PCWSTR FormatStr,
  120. IN ...
  121. );
  122. #define LVL_VERBOSE 10
  123. #define LVL_MEDIUM 5
  124. #define LVL_MINIMAL 1
  125. #define LVL_SILENT 0
  126. //
  127. // must keep the call to dprintf in all builds
  128. //
  129. #define DebugPrint(_lvl_,_fmt_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_)
  130. #define DebugPrint1(_lvl_,_fmt_,_arg1_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_,_arg1_)
  131. #define DebugPrint2(_lvl_,_fmt_,_arg1_,_arg2_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_,_arg1_,_arg2_)
  132. #define DebugPrint3(_lvl_,_fmt_,_arg1_,_arg2_,_arg3_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_,_arg1_,_arg2_,_arg3_)
  133. #define DebugPrint4(_lvl_,_fmt_,_arg1_,_arg2_,_arg3,_arg4_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_,_arg1_,_arg2_,_arg3, _arg4_)
  134. #define DebugPrint5(_lvl_,_fmt_,_arg1_,_arg2_,_arg3, _arg4, _arg5_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_,_arg1_,_arg2_,_arg3, _arg4, _arg5_)
  135. #define DebugPrint6(_lvl_,_fmt_,_arg1_,_arg2_,_arg3, _arg4, _arg5, _arg6_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_,_arg1_,_arg2_,_arg3, _arg4, _arg5, _arg6_)
  136. #define DebugPrint7(_lvl_,_fmt_,_arg1_,_arg2_,_arg3, _arg4, _arg5, _arg6, _arg7_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_,_arg1_,_arg2_,_arg3, _arg4, _arg5, _arg6, _arg7_)
  137. #define DebugPrint8(_lvl_,_fmt_,_arg1_,_arg2_,_arg3, _arg4, _arg5, _arg6, _arg7_, _arg8_) dprintf(_lvl_,TEXT(__FILE__),__LINE__,_fmt_,_arg1_,_arg2_,_arg3, _arg4, _arg5, _arg6, _arg7_, _arg8_)
  138. //
  139. // this hash function was taken from the ntfs driver
  140. //
  141. #define FILENAME_STRING_CONVERT_CONSTANT 314159269 // default value for "scrambling constant"
  142. #define FILENAME_STRING_PRIME 1000000007 // prime number, also used for scrambling
  143. #define HASH_DYN_CONVERT_KEY(_pustr,_len,_phash) \
  144. { \
  145. PCWSTR _p = _pustr; \
  146. PCWSTR _ep = _p + _len; \
  147. ULONG _chHolder =0; \
  148. while( _p < _ep ) { \
  149. _chHolder = 37 * _chHolder + (unsigned int) (*_p++); \
  150. } \
  151. *(_phash) = abs(FILENAME_STRING_CONVERT_CONSTANT * _chHolder) % FILENAME_STRING_PRIME; \
  152. }
  153. #define PARENT_WND_CLASS L"SFC Parent Window Class"
  154. #define REGKEY_WINLOGON L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"
  155. #define REGKEY_SAFEBOOT L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Safeboot\\Option"
  156. #define REGKEY_POLICY L"\\Registry\\Machine\\Software\\Policies\\Microsoft\\Windows NT\\Windows File Protection"
  157. #define REGKEY_POLICY_SETUP L"\\Registry\\Machine\\Software\\Policies\\Microsoft\\Windows NT\\Setup"
  158. #define REGKEY_SETUP_FULL L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup"
  159. #define REGKEY_SETUP L"Software\\Microsoft\\Windows\\CurrentVersion\\Setup"
  160. #define REGKEY_WINDOWS L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion"
  161. #define REGKEY_SESSIONMANAGERSFC L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\SFC"
  162. #define REGVAL_SFCDEBUG L"SfcDebug"
  163. #define REGVAL_SFCDISABLE L"SfcDisable"
  164. #define REGVAL_SFCSCAN L"SfcScan"
  165. #define REGVAL_SFCQUOTA L"SfcQuota"
  166. #define REGVAL_SFCSHOWPROGRESS L"SfcShowProgress"
  167. #ifdef SFCLOGFILE
  168. #define REGVAL_SFCCHANGELOG L"SfcChangeLog"
  169. #endif
  170. #define REGVAL_SFCSTALL L"SfcStall"
  171. #define REGVAL_SFCDLLCACHEDIR L"SfcDllCacheDir"
  172. #define REGVAL_OPTIONVALUE L"OptionValue"
  173. #define REGVAL_SOURCEPATH L"SourcePath"
  174. #define REGVAL_SERVICEPACKSOURCEPATH L"ServicePackSourcePath"
  175. #define REGVAL_DRIVERCACHEPATH L"DriverCachePath"
  176. #define REGVAL_INSTALLFROMCD L"InstallFromCD"
  177. #define REGVAL_INSTALLSPFROMCD L"InstallSpFromCD"
  178. // this is used by the system restore
  179. #define REGVAL_SFCRESTORED L"SFCRestored"
  180. // the path to the log file
  181. #define REGVAL_SFCLOGFILE L"SFCLogFile"
  182. #define REGVAL_SFCLOGFILE_DEFAULT L"%systemroot%\\SFCLog.txt"
  183. #define DLLCACHE_DIR_DEFAULT L"%SystemRoot%\\system32\\DllCache"
  184. typedef struct _SOURCE_INFO {
  185. WCHAR SourceFileName[MAX_PATH];
  186. WCHAR SourceRootPath[MAX_PATH];
  187. WCHAR SourcePath[MAX_PATH];
  188. WCHAR TagFile[MAX_PATH];
  189. WCHAR Description[MAX_PATH];
  190. ULONG SetupAPIFlags;
  191. UINT SourceId;
  192. DWORD Flags;
  193. WCHAR DriverCabName[MAX_PATH];
  194. struct _VALIDATION_REQUEST_DATA *ValidationRequestData;
  195. } SOURCE_INFO, *PSOURCE_INFO;
  196. //
  197. // define valid flags for SOURCE_INFO.Flags
  198. //
  199. #define SI_FLAG_USEDRIVER_CACHE 0x00000001
  200. #define SI_FLAG_USERESTORE_QUEUE 0x00000002
  201. #define SI_FLAG_SILENT_QUEUE 0x00000004
  202. typedef struct _FILE_COPY_INFO {
  203. PVOID MsgHandlerContext;
  204. BOOL UIShown;
  205. BOOL AllowUI;
  206. WCHAR NewPath[MAX_PATH*2];
  207. PFILEINSTALL_STATUS CopyStatus;
  208. HANDLE hWnd;
  209. BOOL CdRomOnly;
  210. DWORD Flags;
  211. DWORD FileCount;
  212. PSOURCE_INFO *si;
  213. } FILE_COPY_INFO, *PFILE_COPY_INFO;
  214. //
  215. // define valid flags for FILE_COPY_INFO.Flags
  216. //
  217. #define FCI_FLAG_USERESTORE_QUEUE 0x00000001
  218. #define FCI_FLAG_SILENT_QUEUE 0x00000002
  219. #define FCI_FLAG_COPY_TO_CACHE 0x00000004
  220. #define FCI_FLAG_INSTALL_PROTECTED 0x00000008
  221. #define FCI_FLAG_RESTORE_FILE 0x00000010
  222. //
  223. // This is the timeout when waitiing all WFP threads to shutdown (1 minute)
  224. //
  225. #define SFC_THREAD_SHUTDOWN_TIMEOUT 60000
  226. typedef struct _PROMPT_INFO {
  227. PWSTR NewPath;
  228. PCWSTR SourceFileName;
  229. PCWSTR SourcePath;
  230. PSOURCE_INFO si;
  231. BOOL NetPrompt;
  232. DWORD Flags;
  233. } PROMPT_INFO, *PPROMPT_INFO;
  234. //
  235. // define valid flags for PROMPT_INFO.Flags
  236. //
  237. #define PI_FLAG_USERESTORE_QUEUE 0x00000001
  238. #define PI_FLAG_SILENT_QUEUE 0x00000002
  239. #define PI_FLAG_COPY_TO_CACHE 0x00000004
  240. #define PI_FLAG_INSTALL_PROTECTED 0x00000008
  241. #define PI_FLAG_RESTORE_FILE 0x00000010
  242. typedef struct _SCAN_PARAMS {
  243. HWND ProgressWindow;
  244. BOOL AllowUI;
  245. BOOL FreeMemory;
  246. } SCAN_PARAMS, *PSCAN_PARAMS;
  247. typedef struct _RESTORE_QUEUE {
  248. RTL_CRITICAL_SECTION CriticalSection;
  249. HSPFILEQ FileQueue;
  250. ULONG QueueCount;
  251. BOOL RestoreInProgress;
  252. BOOL RestoreComplete;
  253. BOOL RestoreStatus;
  254. DWORD LastErrorCode;
  255. HANDLE WorkerThreadHandle;
  256. FILE_COPY_INFO FileCopyInfo;
  257. } RESTORE_QUEUE, * PRESTORE_QUEUE;
  258. //
  259. // descibes a file's version information for display in the eventlog, etc.
  260. //
  261. typedef struct _FILE_VERSION_INFO {
  262. WORD Revision;
  263. WORD BuildNumber;
  264. WORD VersionLow;
  265. WORD VersionHigh;
  266. } FILE_VERSION_INFO, *PFILE_VERSION_INFO;
  267. //
  268. // describes a given file on disk
  269. //
  270. typedef struct _IMAGE_VALIDATION_DATA {
  271. ULONGLONG DllVersion;
  272. ULONG DllCheckSum;
  273. BOOL SignatureValid;
  274. BOOL FilePresent; // is file present on disk?
  275. WCHAR FileName[32];
  276. } IMAGE_VALIDATION_DATA, *PIMAGE_VALIDATION_DATA;
  277. //
  278. // describes a file on disk, in dllcache, etc.
  279. //
  280. typedef struct _COMPLETE_VALIDATION_DATA {
  281. IMAGE_VALIDATION_DATA Original;
  282. IMAGE_VALIDATION_DATA Cache;
  283. IMAGE_VALIDATION_DATA New;
  284. BOOL RestoreFromReal;
  285. BOOL RestoreFromCache;
  286. BOOL RestoreFromMedia;
  287. BOOL NotifyUser;
  288. BOOL BadCacheEntry;
  289. ULONG EventLog;
  290. } COMPLETE_VALIDATION_DATA, *PCOMPLETE_VALIDATION_DATA;
  291. //
  292. // describes a given file in the system
  293. //
  294. typedef struct _SFC_REGISTRY_VALUE {
  295. LIST_ENTRY Entry;
  296. UNICODE_STRING FileName;
  297. UNICODE_STRING DirName;
  298. UNICODE_STRING FullPathName;
  299. UNICODE_STRING InfName;
  300. UNICODE_STRING SourceFileName;
  301. WCHAR OriginalFileName[128];
  302. HANDLE DirHandle;
  303. //
  304. // This is dropped in here from WinSxs (jonwis) - tally up some
  305. // useful information about the directories they want to watch.
  306. // This should be NULL otherwise.
  307. //
  308. PVOID pvWinSxsCookie;
  309. //
  310. // Other flags used by the SFC/SXS interaction, specifically
  311. // whether or not the directory should be watched recursively
  312. // or not.
  313. //
  314. DWORD dwWinSxsFlags;
  315. } SFC_REGISTRY_VALUE, *PSFC_REGISTRY_VALUE;
  316. //
  317. // describes a given directory that we're watching for changes in
  318. //
  319. typedef struct _DIRECTORY_WATCH_DATA {
  320. HANDLE DirHandle;
  321. HANDLE DirEvent;
  322. IO_STATUS_BLOCK Iosb;
  323. PUCHAR WatchBuffer;
  324. PSFC_REGISTRY_VALUE WatchDirectory;
  325. } DIRECTORY_WATCH_DATA, *PDIRECTORY_WATCH_DATA;
  326. //
  327. // describes a file that needs to be replaced
  328. //
  329. typedef struct _VALIDATION_REQUEST_DATA {
  330. LIST_ENTRY Entry;
  331. ULONG Signature;
  332. COMPLETE_VALIDATION_DATA ImageValData;
  333. PSFC_REGISTRY_VALUE RegVal;
  334. //
  335. // records the source information for this
  336. // file
  337. //
  338. SOURCE_INFO SourceInfo;
  339. ULONG ChangeType;
  340. //
  341. // indicates that the file has been validated
  342. // and the good file copied back
  343. //
  344. BOOL CopyCompleted;
  345. //
  346. // indicates win32 error code if an error occurs while
  347. // restoring the file
  348. //
  349. DWORD Win32Error;
  350. //
  351. // this flag prevents the validator from logging
  352. // file changes when we have to put a file into the cache
  353. //
  354. BOOL SyncOnly;
  355. //
  356. // in case of errors we need to track the
  357. // count so we don't loop on one file forever
  358. //
  359. DWORD RetryCount;
  360. //
  361. // flags for validation request item
  362. //
  363. DWORD Flags;
  364. //
  365. // this value contains a tick count and is
  366. // used to pause the queue for a specific file.
  367. // this is necessary so that rename/copy operations
  368. // can work properly.
  369. //
  370. ULONG NextValidTime;
  371. } VALIDATION_REQUEST_DATA, *PVALIDATION_REQUEST_DATA;
  372. //
  373. // define valid flags for VALIDATION_REQUEST_DATA.Flags
  374. //
  375. #define VRD_FLAG_REQUEST_PROCESSED 0x00000001
  376. #define VRD_FLAG_REQUIRE_UI 0x00000002
  377. #define VRD_FLAG_REQUEST_QUEUED 0x00000004
  378. typedef struct _WATCH_THREAD_PARAMS {
  379. PHANDLE HandleList;
  380. DWORD HandleCount;
  381. PDIRECTORY_WATCH_DATA DirectoryWatchList;
  382. } WATCH_THREAD_PARAMS, *PWATCH_THREAD_PARAMS;
  383. //
  384. // Describes a system dialog that may be brought up. We need a structure to keep
  385. // track of the windows so that we can tear them down on logoff or system
  386. // shutdown
  387. //
  388. typedef struct _SFC_WINDOW_DATA {
  389. LIST_ENTRY Entry;
  390. HWND hWnd;
  391. DWORD ThreadId;
  392. //HANDLE hEvent;
  393. } SFC_WINDOW_DATA, *PSFC_WINDOW_DATA;
  394. //
  395. // externs
  396. //
  397. extern PSFC_REGISTRY_VALUE SfcProtectedDllsList;
  398. extern ULONG SfcProtectedDllCount;
  399. extern HMODULE SfcInstanceHandle;
  400. extern LIST_ENTRY SfcErrorQueue;
  401. extern HANDLE ErrorQueuePort;
  402. extern HANDLE hErrorThread;
  403. extern HANDLE ErrorQueueEvent;
  404. extern ULONG ErrorQueueCount;
  405. extern HANDLE SfcProtectedDllFileDirectory;
  406. extern RTL_CRITICAL_SECTION ErrorCs;
  407. extern ULONG SFCDisable;
  408. extern ULONG SFCScan;
  409. extern ULONGLONG SFCQuota;
  410. extern ULONG SFCNoPopUps;
  411. extern ULONG SFCNoPopUpsPolicy;
  412. extern WORD SFCDebugDump;
  413. extern WORD SFCDebugLog;
  414. extern WCHAR g_szLogFile[MAX_PATH];
  415. #ifdef SFCLOGFILE
  416. extern ULONG SFCChangeLog;
  417. #endif
  418. extern ULONG SFCStall;
  419. extern ULONG SFCSafeBootMode;
  420. extern ULONG InstallFromCD;
  421. extern ULONG InstallSpFromCD;
  422. extern HANDLE hEventDeskTop;
  423. extern HANDLE hEventLogon;
  424. extern HANDLE hEventLogoff;
  425. extern UNICODE_STRING SfcProtectedDllPath;
  426. extern LIST_ENTRY SfcWatchDirectoryList;
  427. extern GUID DriverVerifyGuid;
  428. extern HANDLE WatchTermEvent;
  429. extern HANDLE ValidateTermEvent;
  430. extern HANDLE WatcherThread;
  431. #if DBG
  432. extern HANDLE SfcDebugBreakEvent;
  433. extern ULONG RunningAsTest;
  434. #endif
  435. extern WCHAR LoggedOnUserName[MAX_PATH];
  436. extern BOOL UserLoggedOn;
  437. extern HANDLE hEventScanCancel;
  438. extern HANDLE hEventScanCancelComplete;
  439. extern WCHAR OsSourcePath[MAX_PATH*2];
  440. extern WCHAR ServicePackSourcePath[MAX_PATH*2];
  441. extern WCHAR DriverCacheSourcePath[MAX_PATH*2];
  442. extern WCHAR InfDirectory[MAX_PATH];
  443. extern BOOL ScanInProgress;
  444. extern HANDLE hEventSrc;
  445. extern BOOL g_bCryptoInitialized;
  446. extern RTL_CRITICAL_SECTION g_GeneralCS;
  447. extern DWORD g_dwValidationThreadID;
  448. extern DWORD m_gulAfterRestore;
  449. extern ULONG* IgnoreNextChange;
  450. extern ULARGE_INTEGER LastExemptionTime;
  451. //
  452. // This event is signalled when WFP is idle and no longer processing any
  453. // validation requests. An external process can synchronize on this process
  454. // so that it knows WFP is idle before shutting down the system
  455. //
  456. extern HANDLE hEventIdle;
  457. //
  458. // set to TRUE if SFC prompted the user for credentials
  459. //
  460. extern BOOL SFCLoggedOn;
  461. //
  462. // path to the network share that we established network connection to
  463. //
  464. extern WCHAR SFCNetworkLoginLocation[MAX_PATH];
  465. extern RESTORE_QUEUE SilentRestoreQueue;
  466. extern RESTORE_QUEUE UIRestoreQueue;
  467. //
  468. // keeps track of windows that SFC creates in the system.
  469. //
  470. extern LIST_ENTRY SfcWindowList;
  471. //
  472. // handles to user's desktop and token
  473. //
  474. extern HDESK hUserDesktop;
  475. extern HANDLE hUserToken;
  476. //
  477. // indicates if WFP can receive anymore validation requests or not.
  478. //
  479. extern BOOL ShuttingDown;
  480. //
  481. // HINSTANCE of a (possibly) loaded Sxs.dll for notification purposes
  482. //
  483. extern HMODULE SxsDllInstance;
  484. //
  485. // This function gets called back when a change is noticed in the SXS
  486. // protected functions.
  487. //
  488. extern PSXS_PROTECT_NOTIFICATION SxsNotification;
  489. //
  490. // This function is called once to let SXS offer a list of protected
  491. // directories.
  492. //
  493. extern PSXS_PROTECT_RETRIEVELISTS SxsGatherLists;
  494. //
  495. // Notification functions for logon/logoff events to let SXS do whatever
  496. // they need to.
  497. //
  498. extern PSXS_PROTECT_LOGIN_EVENT SxsLogonEvent;
  499. extern PSXS_PROTECT_LOGIN_EVENT SxsLogoffEvent;
  500. //
  501. // Single-shot scanner function to let SxS do its own scanning routine.
  502. //
  503. extern PSXS_PROTECT_SCAN_ONCE SxsScanForcedFunc;
  504. //
  505. // prototypes
  506. //
  507. BOOL
  508. WINAPI
  509. CryptCATAdminAcquireContext(
  510. OUT HCATADMIN *phCatAdmin,
  511. IN const GUID *pgSubsystem,
  512. IN DWORD dwFlags
  513. );
  514. BOOL
  515. WINAPI
  516. CryptCATAdminReleaseContext(
  517. IN HCATADMIN hCatAdmin,
  518. IN DWORD dwFlags
  519. );
  520. BOOL
  521. WINAPI
  522. CryptCATAdminCalcHashFromFileHandle(
  523. IN HANDLE hFile,
  524. IN OUT DWORD *pcbHash,
  525. OUT OPTIONAL BYTE *pbHash,
  526. IN DWORD dwFlags
  527. );
  528. HCATINFO
  529. WINAPI
  530. CryptCATAdminEnumCatalogFromHash(
  531. IN HCATADMIN hCatAdmin,
  532. IN BYTE *pbHash,
  533. IN DWORD cbHash,
  534. IN DWORD dwFlags,
  535. IN OUT HCATINFO *phPrevCatInfo
  536. );
  537. LONG
  538. WINAPI
  539. WinVerifyTrust(
  540. HWND hwnd,
  541. GUID *pgActionID,
  542. LPVOID pWVTData
  543. );
  544. BOOL
  545. WINAPI
  546. CryptCATCatalogInfoFromContext(
  547. IN HCATINFO hCatInfo,
  548. IN OUT CATALOG_INFO *psCatInfo,
  549. IN DWORD dwFlags
  550. );
  551. BOOL
  552. WINAPI
  553. CryptCATAdminReleaseCatalogContext(
  554. IN HCATADMIN hCatAdmin,
  555. IN HCATINFO hCatInfo,
  556. IN DWORD dwFlags
  557. );
  558. //
  559. // Imports from sfcfiles.dll (loaded dynamically)
  560. //
  561. typedef NTSTATUS (*PSFC_GET_FILES)(
  562. OUT PPROTECT_FILE_ENTRY *Files,
  563. OUT PULONG FileCount
  564. );
  565. PVOID
  566. SfcGetProcAddress(
  567. HMODULE hModule,
  568. LPSTR ProcName
  569. );
  570. HMODULE
  571. SfcLoadLibrary(
  572. IN PCWSTR LibFileName
  573. );
  574. NTSTATUS
  575. SfcOpenFile(
  576. IN PUNICODE_STRING FileName,
  577. IN HANDLE DirHandle,
  578. IN ULONG SharingFlags,
  579. OUT PHANDLE FileHandle
  580. );
  581. HANDLE
  582. SfcCreateDir(
  583. IN PCWSTR DirName,
  584. IN BOOL UseCompression
  585. );
  586. HANDLE
  587. SfcOpenDir(
  588. BOOL IsDosName,
  589. BOOL IsSynchronous,
  590. PCWSTR DirName
  591. );
  592. BOOL
  593. SfcValidateDLL(
  594. IN PVALIDATION_REQUEST_DATA vrd,
  595. IN HCATADMIN hCatAdmin
  596. );
  597. BOOL
  598. SfcValidateFileSignature(
  599. IN HCATADMIN hCatAdmin,
  600. IN HANDLE RealFileHandle,
  601. IN PCWSTR BaseFileName,
  602. IN PCWSTR CompleteFileName
  603. );
  604. #if DBG
  605. VOID
  606. PrintHandleCount(
  607. PCWSTR str
  608. );
  609. #endif
  610. NTSTATUS
  611. SfcCopyFile(
  612. IN HANDLE SrcDirHandle,
  613. IN PCWSTR SrcDirName,
  614. IN HANDLE DstDirHandle,
  615. IN PCWSTR DstDirName,
  616. IN const PUNICODE_STRING FileName,
  617. IN const PUNICODE_STRING SourceFileName OPTIONAL
  618. );
  619. NTSTATUS
  620. SfcMoveFileDelayed(
  621. IN PCWSTR OldFileNameDos,
  622. IN PCWSTR NewFileNameDos,
  623. IN BOOL AllowProtectedRename
  624. );
  625. BOOL
  626. SfcReportEvent(
  627. IN ULONG EventId,
  628. IN PCWSTR FileName,
  629. IN PCOMPLETE_VALIDATION_DATA ImageValData,
  630. IN DWORD LastError OPTIONAL
  631. );
  632. //ULONGLONG
  633. //SfcGetFileVersion(
  634. // IN HANDLE FileHandle,
  635. // OUT PULONG CheckSum,
  636. // OUT PWSTR FileName
  637. // );
  638. BOOL
  639. SfcGetFileVersion(
  640. IN HANDLE FileHandle,
  641. OUT PULONGLONG Version,
  642. OUT PULONG Checksum,
  643. OUT PWSTR FileName
  644. );
  645. NTSTATUS
  646. SfcMapEntireFile(
  647. IN HANDLE hFile,
  648. OUT PHANDLE Section,
  649. OUT PVOID *ViewBase,
  650. OUT PSIZE_T ViewSize
  651. );
  652. BOOL
  653. SfcUnmapFile(
  654. IN HANDLE Section,
  655. IN PVOID ViewBase
  656. );
  657. NTSTATUS
  658. LoadCrypto(
  659. VOID
  660. );
  661. NTSTATUS
  662. SfcScanProtectedDlls(
  663. PSCAN_PARAMS ScanParams
  664. );
  665. NTSTATUS
  666. SfcStartProtectedDirectoryWatch(
  667. void
  668. );
  669. BOOL
  670. SfcBuildDirectoryWatchList(
  671. void
  672. );
  673. NTSTATUS
  674. SfcDeleteFile(
  675. HANDLE DirHandle,
  676. PUNICODE_STRING FileName
  677. );
  678. BOOL
  679. SfcRestoreFileFromInstallMedia(
  680. IN PVALIDATION_REQUEST_DATA vrd,
  681. IN PCWSTR FileName,
  682. IN PCWSTR TargetFileName,
  683. IN PCWSTR TargetDirectory,
  684. IN PCWSTR SourceFileName,
  685. IN PCWSTR InfName,
  686. IN BOOL ExcepPackFile,
  687. IN BOOL TargetIsCache,
  688. IN BOOL AllowUI,
  689. OUT PDWORD UIShown
  690. );
  691. DWORD
  692. MyMessageBox(
  693. HWND hwndParent,
  694. DWORD ResId,
  695. DWORD MsgBoxType,
  696. ...
  697. );
  698. ULONG
  699. SfcQueryRegDword(
  700. IN PCWSTR KeyNameStr,
  701. IN PCWSTR ValueNameStr,
  702. IN ULONG DefaultValue
  703. );
  704. ULONG
  705. SfcQueryRegDwordWithAlternate(
  706. IN PCWSTR FirstKey,
  707. IN PCWSTR SecondKey,
  708. IN PCWSTR ValueNameStr,
  709. IN ULONG DefaultValue
  710. );
  711. PVOID
  712. MemAlloc(
  713. SIZE_T AllocSize
  714. );
  715. PVOID
  716. MemReAlloc(
  717. SIZE_T AllocSize,
  718. PVOID OrigPtr
  719. );
  720. VOID
  721. MemFree(
  722. PVOID MemPtr
  723. );
  724. ULONG
  725. SfcWriteRegDword(
  726. PCWSTR KeyNameStr,
  727. PCWSTR ValueNameStr,
  728. ULONG Value
  729. );
  730. ULONG
  731. SfcWriteRegString(
  732. PCWSTR KeyNameStr,
  733. PCWSTR ValueNameStr,
  734. PCWSTR Value
  735. );
  736. BOOL
  737. EnablePrivilege(
  738. IN PCTSTR PrivilegeName,
  739. IN BOOL Enable
  740. );
  741. PVOID
  742. SfcFindProtectedFile(
  743. IN PCWSTR FileName,
  744. IN ULONG FileNameLength // in characters
  745. );
  746. PWSTR
  747. SfcQueryRegString(
  748. IN PCWSTR KeyNameStr,
  749. IN PCWSTR ValueNameStr
  750. );
  751. ULONG
  752. SfcQueryRegPath(
  753. IN PCWSTR KeyNameStr,
  754. IN PCWSTR ValueNameStr,
  755. IN PCWSTR DefaultValue OPTIONAL,
  756. OUT PWSTR Buffer,
  757. IN ULONG BufferSize
  758. );
  759. PWSTR
  760. SfcQueryRegStringWithAlternate(
  761. IN PCWSTR FirstKey,
  762. IN PCWSTR SecondKey,
  763. IN PCWSTR ValueNameStr
  764. );
  765. NTSTATUS
  766. SfcQueueValidationRequest(
  767. IN PSFC_REGISTRY_VALUE RegVal,
  768. IN ULONG ChangeType
  769. );
  770. void
  771. MyLowerString(
  772. IN PWSTR String,
  773. IN ULONG StringLength // in characters
  774. );
  775. #ifdef SFCLOGFILE
  776. void
  777. SfcLogFileWrite(
  778. IN DWORD StrId,
  779. IN ...
  780. );
  781. #endif
  782. BOOL
  783. SfcPopulateCache(
  784. IN HWND ProgressWindow,
  785. IN BOOL Validate,
  786. IN BOOL AllowUI,
  787. IN PCWSTR IgnoreFiles OPTIONAL
  788. );
  789. NTSTATUS
  790. SfcDoForcedSxsScan(
  791. IN HWND ProgressWindow,
  792. IN BOOL Validate,
  793. IN BOOL AllowUI
  794. );
  795. BOOL
  796. SfcLoadSxsProtection(
  797. void
  798. );
  799. BOOL
  800. SfcAddFileToQueue(
  801. IN const HSPFILEQ hFileQ,
  802. IN PCWSTR FileName,
  803. IN PCWSTR TargetFileName,
  804. IN PCWSTR TargetDirectory,
  805. IN PCWSTR SourceFileName, OPTIONAL
  806. IN PCWSTR SourceRootPath, OPTIONAL
  807. IN PCWSTR InfName,
  808. IN BOOL ExcepPackFile,
  809. IN OUT PSOURCE_INFO SourceInfo OPTIONAL
  810. );
  811. UINT
  812. SfcQueueCallback(
  813. IN PFILE_COPY_INFO fci,
  814. IN UINT Notification,
  815. IN UINT_PTR Param1,
  816. IN UINT_PTR Param2
  817. );
  818. NTSTATUS
  819. SfcInitializeDllLists(
  820. PSFC_GET_FILES pfGetFiles
  821. );
  822. void
  823. RemoveDuplicatesFromQueue(
  824. IN PSFC_REGISTRY_VALUE RegVal
  825. );
  826. int
  827. MyDialogBoxParam(
  828. IN DWORD RcId,
  829. IN DLGPROC lpDialogFunc, // pointer to dialog box procedure
  830. IN LPARAM dwInitParam // initialization value
  831. );
  832. BOOL
  833. SfcGetValidationData(
  834. IN PUNICODE_STRING FileName,
  835. IN PUNICODE_STRING FullPathName,
  836. IN HANDLE DirHandle,
  837. IN HCATADMIN hCatAdmin,
  838. OUT PIMAGE_VALIDATION_DATA ImageValData
  839. );
  840. void
  841. CenterDialog(
  842. HWND hwnd
  843. );
  844. BOOL
  845. MakeDirectory(
  846. PCWSTR Dir
  847. );
  848. void
  849. ClientApiInit(
  850. void
  851. );
  852. void
  853. ClientApiCleanup(
  854. void
  855. );
  856. BOOL
  857. SfcGetSourceInformation(
  858. IN PCWSTR SourceFileName,
  859. IN PCWSTR InfName,
  860. IN BOOL ExcepPackFile,
  861. OUT PSOURCE_INFO si
  862. );
  863. BOOL
  864. SfcGetCdRomDrivePath(
  865. IN PWSTR CdRomPath
  866. );
  867. BOOL
  868. SfcpSetSpecialEnvironmentVariables(
  869. VOID
  870. );
  871. DWORD
  872. SfcGetPathType(
  873. IN PCWSTR Path,
  874. OUT PWSTR NewPath,
  875. IN DWORD NewPathSize
  876. );
  877. #if 0
  878. DWORD
  879. SfcIsTargetAvailable(
  880. IN PCWSTR InfName,
  881. IN PCWSTR SourceFileName,
  882. IN BOOL TargetIsCache,
  883. OUT PWSTR NewSourcePath,
  884. IN OUT PSOURCE_INFO si
  885. );
  886. #endif
  887. BOOL
  888. SfcRestoreFromCache(
  889. IN PVALIDATION_REQUEST_DATA vrd,
  890. IN HCATADMIN hCatAdmin
  891. );
  892. BOOL
  893. SfcSyncCache(
  894. IN PVALIDATION_REQUEST_DATA vrd,
  895. IN HCATADMIN hCatAdmin
  896. );
  897. PVALIDATION_REQUEST_DATA
  898. IsFileInQueue(
  899. IN PSFC_REGISTRY_VALUE RegVal
  900. );
  901. DWORD
  902. SfcQueueLookForFile(
  903. IN const PSOURCE_MEDIA sm,
  904. IN const PSOURCE_INFO si,
  905. IN PCWSTR fname,
  906. OUT PWSTR NewPath
  907. );
  908. BOOL
  909. SfcQueueAddFileToRestoreQueue(
  910. IN BOOL RequiresUI,
  911. IN PSFC_REGISTRY_VALUE RegVal,
  912. IN PCWSTR InfFileName,
  913. IN BOOL ExcepPackFile,
  914. IN PSOURCE_INFO SourceInfo,
  915. IN PCWSTR ActualFileNameOnMedia
  916. );
  917. BOOL
  918. SfcQueueCommitRestoreQueue(
  919. IN BOOL RequiresUI
  920. );
  921. BOOL
  922. SfcQueueResetQueue(
  923. IN BOOL RequiresUI
  924. );
  925. PSOURCE_INFO
  926. pSfcGetSourceInfoFromSourceName(
  927. const PSOURCE_INFO *SourceInfoList,
  928. DWORD SourceInfoCount,
  929. const PSOURCE_MEDIA SourceMediaInfo
  930. );
  931. PVALIDATION_REQUEST_DATA
  932. pSfcGetValidationRequestFromFilePaths(
  933. const PSOURCE_INFO *SourceInfoList,
  934. DWORD SourceInfoCount,
  935. const PFILEPATHS FilePaths
  936. );
  937. BOOL
  938. SfcGetConnectionName(
  939. IN PCWSTR Path,
  940. OUT PWSTR ConnectionName,
  941. IN DWORD ConnectionBufferSize,
  942. OUT PWSTR RemainingPath OPTIONAL,
  943. IN DWORD RemainingPathSize OPTIONAL,
  944. IN BOOL KeepImpersonating,
  945. OUT PBOOL Impersonating OPTIONAL
  946. );
  947. DWORD
  948. GetPageFileSize(
  949. VOID
  950. );
  951. BOOL
  952. SfcIsFileOnMedia(
  953. IN PCWSTR FileName
  954. );
  955. PCWSTR
  956. IsFileInDriverCache(
  957. IN PCWSTR TargetFilename
  958. );
  959. INT_PTR
  960. CALLBACK
  961. pSfcPromptForMediaDialogProc(
  962. HWND hwndDlg,
  963. UINT uMsg,
  964. WPARAM wParam,
  965. LPARAM lParam
  966. );
  967. PSFC_WINDOW_DATA
  968. pSfcCreateWindowDataEntry(
  969. HWND hWnd
  970. );
  971. BOOL
  972. pSfcRemoveWindowDataEntry(
  973. PSFC_WINDOW_DATA WindowData
  974. );
  975. DWORD
  976. EstablishConnection(
  977. IN HWND hWndParent,
  978. IN PCWSTR PathName,
  979. IN BOOL AllowUI
  980. );
  981. BOOL
  982. BuildPathForFile(
  983. IN PCWSTR SourceRootPath,
  984. IN PCWSTR SubDirectoryPath, OPTIONAL
  985. IN PCWSTR FileName,
  986. IN BOOL IncludeSubDirectory,
  987. IN BOOL IncludeArchitectureSpecificSubDirectory,
  988. OUT PWSTR PathBuffer,
  989. IN DWORD PathBufferSize
  990. );
  991. BOOL
  992. SfcWaitForValidDesktop(
  993. VOID
  994. );
  995. PWSTR
  996. SfcGetSourcePath(
  997. IN BOOL bServicePackSourcePath,
  998. IN OUT PWSTR Path
  999. );
  1000. DWORD
  1001. SfcRpcPriviledgeCheck(
  1002. IN HANDLE RpcHandle
  1003. );
  1004. void
  1005. SfcFlushCryptoCache(
  1006. void
  1007. );
  1008. PSFC_GET_FILES
  1009. SfcLoadSfcFiles(
  1010. BOOL bLoad
  1011. );
  1012. DWORD
  1013. CreateSd(
  1014. PSECURITY_DESCRIPTOR* ppsd
  1015. );
  1016. VOID
  1017. SfcExceptionInfoInit(
  1018. VOID
  1019. );
  1020. VOID
  1021. SfcRefreshExceptionInfo(
  1022. VOID
  1023. );
  1024. BOOL
  1025. SfcGetInfName(
  1026. IN PSFC_REGISTRY_VALUE RegVal,
  1027. OUT LPWSTR InfName
  1028. );
  1029. DWORD
  1030. CreateDialogParent(
  1031. OUT HWND* phwnd
  1032. );
  1033. NTSTATUS
  1034. SfcAllocUnicodeStringFromPath(
  1035. IN PCWSTR szPath,
  1036. OUT PUNICODE_STRING pString
  1037. );
  1038. #ifndef _WIN64
  1039. VOID
  1040. SfcInitPathTranslator(
  1041. VOID
  1042. );
  1043. VOID
  1044. SfcCleanupPathTranslator(
  1045. IN BOOL FinalCleanup
  1046. );
  1047. NTSTATUS
  1048. SfcRedirectPath(
  1049. IN PCWSTR szPath,
  1050. OUT PUNICODE_STRING pPath
  1051. );
  1052. #endif // _WIN64
  1053. HINF
  1054. SfcOpenInf(
  1055. IN PCWSTR InfName OPTIONAL,
  1056. IN BOOL ExcepPackInf
  1057. );
  1058. FORCEINLINE
  1059. ULONG
  1060. SfcGetExemptionFlags(
  1061. IN PSFC_REGISTRY_VALUE RegVal
  1062. )
  1063. {
  1064. UINT_PTR Index;
  1065. ASSERT(RegVal != NULL);
  1066. Index = RegVal - SfcProtectedDllsList;
  1067. ASSERT(Index < SfcProtectedDllCount);
  1068. return Index < SfcProtectedDllCount ? IgnoreNextChange[Index] : 0;
  1069. }
  1070. FORCEINLINE
  1071. VOID
  1072. SfcSetExemptionFlags(
  1073. IN PSFC_REGISTRY_VALUE RegVal,
  1074. IN ULONG Flags
  1075. )
  1076. {
  1077. UINT_PTR Index;
  1078. ASSERT(RegVal != NULL);
  1079. Index = RegVal - SfcProtectedDllsList;
  1080. ASSERT(Index < SfcProtectedDllCount);
  1081. if(Index < SfcProtectedDllCount) {
  1082. IgnoreNextChange[Index] |= Flags;
  1083. }
  1084. }
  1085. FORCEINLINE
  1086. ULARGE_INTEGER
  1087. SfcGetSystemTime(
  1088. VOID
  1089. )
  1090. {
  1091. FILETIME filetime;
  1092. ULARGE_INTEGER time;
  1093. GetSystemTimeAsFileTime(&filetime);
  1094. time.LowPart = filetime.dwLowDateTime;
  1095. time.HighPart = filetime.dwHighDateTime;
  1096. return time;
  1097. }
  1098. FORCEINLINE
  1099. BOOL
  1100. SfcAreExemptionFlagsValid(
  1101. BOOL ResetValidityTimer
  1102. )
  1103. {
  1104. //
  1105. // one minute in 100-nanosecond units
  1106. //
  1107. const ULARGE_INTEGER ExemptionFlagsTimeout = { 10000000 * 60 };
  1108. ULARGE_INTEGER time = SfcGetSystemTime();
  1109. BOOL Valid = (time.QuadPart - LastExemptionTime.QuadPart < ExemptionFlagsTimeout.QuadPart);
  1110. if(ResetValidityTimer) {
  1111. LastExemptionTime.QuadPart = time.QuadPart;
  1112. }
  1113. return Valid;
  1114. }