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.

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