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.

2063 lines
43 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. pfsvc.h
  5. Abstract:
  6. This module contains private declarations for the prefetcher
  7. service responsible for maintaining prefetch scenario files.
  8. Author:
  9. Stuart Sechrest (stuartse)
  10. Cenk Ergan (cenke)
  11. Chuck Leinzmeier (chuckl)
  12. Environment:
  13. User Mode
  14. --*/
  15. #ifndef _PFSVC_H_
  16. #define _PFSVC_H_
  17. //
  18. // This is the version of the prefetcher maintenance service. It does
  19. // not have to be in sync with the the prefetcher PF_CURRENT_VERSION.
  20. //
  21. #define PFSVC_SERVICE_VERSION 15
  22. //
  23. // This is the maximum number of traces that will be acquired from the
  24. // kernel and put on the list in the service waiting to be processed.
  25. //
  26. #define PFSVC_MAX_NUM_QUEUED_TRACES 100
  27. //
  28. // If the number of faults in a trace period falls below this, that
  29. // marks the end of the trace for some scenario types.
  30. //
  31. #define PFSVC_MIN_FAULT_THRESHOLD 10
  32. //
  33. // What the rate of usage for the pages we prefetched should be
  34. // greater than for us not to increase scenario sensitivity.
  35. //
  36. #define PFSVC_MIN_HIT_PERCENTAGE 90
  37. //
  38. // What the rate of usage for the pages we knew about but ignored
  39. // should be less than for us not to decrease scenario sensitivity.
  40. //
  41. #define PFSVC_MAX_IGNORED_PERCENTAGE 30
  42. //
  43. // This is the number of launches after which we will set the
  44. // MinReTraceTime and MinRePrefetchTime's on the scenario's header to
  45. // limit prefetch activity if a scenario gets launched very
  46. // frequently. This allows short training scenarios to be run before
  47. // benchmarking after deleting the prefetch files.
  48. //
  49. #define PFSVC_MIN_LAUNCHES_FOR_LAUNCH_FREQ_CHECK 10
  50. //
  51. // This is the default time in 100ns that has to pass from the last
  52. // launch of a scenario before we prefetch it again.
  53. //
  54. #define PFSVC_DEFAULT_MIN_REPREFETCH_TIME (1i64 * 120 * 1000 * 1000 * 10)
  55. //
  56. // This is the default time in 100ns that has to pass from the last
  57. // launch of a scenario before we re-trace it again.
  58. //
  59. #define PFSVC_DEFAULT_MIN_RETRACE_TIME (1i64 * 120 * 1000 * 1000 * 10)
  60. //
  61. // This is the maximum number of prefetch scenario files we'll have in
  62. // the prefetch directory. Once we reach this amount we won't create
  63. // new scenario files until we clean up the old ones.
  64. //
  65. #if DBG
  66. #define PFSVC_MAX_PREFETCH_FILES 12
  67. #else // DBG
  68. #define PFSVC_MAX_PREFETCH_FILES 128
  69. #endif // DBG
  70. //
  71. // Path to the registry key and name of the value that specifies the
  72. // file the defragger uses to determine optimal layout of files on the
  73. // disk.
  74. //
  75. #define PFSVC_OPTIMAL_LAYOUT_REG_KEY_PATH \
  76. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\OptimalLayout"
  77. #define PFSVC_OPTIMAL_LAYOUT_REG_VALUE_NAME \
  78. L"LayoutFilePath"
  79. #define PFSVC_OPTIMAL_LAYOUT_FILE_DEFAULT_NAME \
  80. L"Layout.ini"
  81. #define PFSVC_OPTIMAL_LAYOUT_ENABLE_VALUE_NAME \
  82. L"EnableAutoLayout"
  83. //
  84. // Path to the registry key under which we store various service data,
  85. // e.g. version, last time the defragger was run successfully to
  86. // update layout etc.
  87. //
  88. #define PFSVC_SERVICE_DATA_KEY \
  89. L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Prefetcher"
  90. //
  91. // These are the value names under PFSVC_SERVICE_DATA_KEY in which we
  92. // store various prefetcher service data.
  93. //
  94. #define PFSVC_VERSION_VALUE_NAME \
  95. L"Version"
  96. #define PFSVC_START_TIME_VALUE_NAME \
  97. L"StartTime"
  98. #define PFSVC_EXIT_TIME_VALUE_NAME \
  99. L"ExitTime"
  100. #define PFSVC_EXIT_CODE_VALUE_NAME \
  101. L"ExitCode"
  102. #define PFSVC_LAST_DISK_LAYOUT_TIME_STRING_VALUE_NAME \
  103. L"LastDiskLayoutTimeString"
  104. #define PFSVC_TRACES_PROCESSED_VALUE_NAME \
  105. L"TracesProcessed"
  106. #define PFSVC_TRACES_SUCCESSFUL_VALUE_NAME \
  107. L"TracesSuccessful"
  108. #define PFSVC_LAST_TRACE_FAILURE_VALUE_NAME \
  109. L"LastTraceFailure"
  110. #define PFSVC_BOOT_FILES_OPTIMIZED_VALUE_NAME \
  111. L"BootFilesOptimized"
  112. #define PFSVC_MIN_RELAYOUT_HOURS_VALUE_NAME \
  113. L"MinRelayoutHours"
  114. //
  115. // This is the value name under PFSVC_SERVICE_DATA_KEY in which we
  116. // store the last time the defragger was run successfully to update
  117. // layout.
  118. //
  119. #define PFSVC_LAST_DISK_LAYOUT_TIME_VALUE_NAME \
  120. L"LastDiskLayoutTime"
  121. //
  122. // This is the registry path to the NLS configuration key.
  123. //
  124. #define PFSVC_NLS_REG_KEY_PATH \
  125. L"SYSTEM\\CurrentControlSet\\Control\\Nls"
  126. //
  127. // This is the name of the named manual-reset event that can be set to
  128. // override waiting for system to be idle before processing traces.
  129. //
  130. #define PFSVC_OVERRIDE_IDLE_EVENT_NAME L"PrefetchOverrideIdle"
  131. //
  132. // This is the name of the named manual-reset event that will be set
  133. // when there are no traces left to process.
  134. //
  135. #define PFSVC_PROCESSING_COMPLETE_EVENT_NAME L"PrefetchProcessingComplete"
  136. //
  137. // When we have run the defragger for all drives after a setup / upgrade,
  138. // we set the build status registry value to this string:
  139. //
  140. #define PFSVC_DEFRAG_DRIVES_DONE L"DefragDone"
  141. //
  142. // Number of 100ns in an hour.
  143. //
  144. #define PFSVC_NUM_100NS_IN_AN_HOUR (1i64 * 60 * 60 * 1000 * 1000 * 10)
  145. //
  146. // This is how many 100ns have to pass since last disk layout for us to do
  147. // another one, if we are not being explicitly run.
  148. //
  149. #define PFSVC_MIN_TIME_BEFORE_DISK_RELAYOUT (1i64 * 3 * 24 * PFSVC_NUM_100NS_IN_AN_HOUR)
  150. //
  151. // Allocation granularity for trace buffers.
  152. //
  153. #define ROUND_TRACE_BUFFER_SIZE(_required) (((_required) + 16384 - 1) & ~(16384 - 1))
  154. //
  155. // Define useful macros. As with all macros, must be careful of parameter
  156. // reevalation. Don't use expressions as macro parameters.
  157. //
  158. #define PFSVC_ALLOC(NumBytes) (HeapAlloc(GetProcessHeap(),0,(NumBytes)))
  159. #define PFSVC_FREE(Buffer) (HeapFree(GetProcessHeap(),0,(Buffer)))
  160. //
  161. // This magic is used to mark free'd memory in chunk allocator.
  162. //
  163. #define PFSVC_CHUNK_ALLOCATOR_FREED_MAGIC 0xFEEDCEED
  164. //
  165. // This magic is used to mark free'd memory in string allocator.
  166. //
  167. #define PFSVC_STRING_ALLOCATOR_FREED_MAGIC 0xFEED
  168. //
  169. // This is the max size for the strings allocated from the string
  170. // allocator that will be allocated from the preallocated buffer, so we
  171. // can save the size of the allocation with the header in a USHORT.
  172. //
  173. #define PFSVC_STRING_ALLOCATOR_MAX_BUFFER_ALLOCATION_SIZE 60000
  174. //
  175. // These macros are used to acquire/release a mutex.
  176. //
  177. #define PFSVC_ACQUIRE_LOCK(Lock) \
  178. DBGPR((PFID,PFLOCK,"PFSVC: AcquireLock-Begin(%s,%d,%s)\n",#Lock,__LINE__,__FILE__));\
  179. WaitForSingleObject((Lock), INFINITE); \
  180. DBGPR((PFID,PFLOCK,"PFSVC: AcquireLock-End(%s,%d,%s)\n",#Lock,__LINE__,__FILE__)); \
  181. #define PFSVC_RELEASE_LOCK(Lock) \
  182. ReleaseMutex((Lock)); \
  183. DBGPR((PFID,PFLOCK,"PFSVC: ReleaseLock(%s,%d,%s)\n",#Lock,__LINE__,__FILE__)); \
  184. //
  185. // Internal type and constant definitions: Entries in the trace and in
  186. // the existing scenario file are put into these structures for easier
  187. // manipulation and policy implementation.
  188. //
  189. typedef struct _PFSVC_SECTION_NODE {
  190. // ISSUE-2002/03/29-ScottMa -- Anonymous unions are no longer supported by
  191. // the compiler. They are a non-standard extension (see MSDN -- C4201).
  192. // There are three such unions/structs below.
  193. union {
  194. //
  195. // Link in the scenarios list of section nodes.
  196. //
  197. LIST_ENTRY SectionLink;
  198. //
  199. // These fields are used to sort section nodes by first
  200. // access.
  201. //
  202. struct {
  203. struct _PFSVC_SECTION_NODE *LeftChild;
  204. struct _PFSVC_SECTION_NODE *RightChild;
  205. };
  206. };
  207. //
  208. // Filesystem index number for this section is saved here if it is
  209. // retrieved. If the section node is for the MFT for the volume we
  210. // save the number of pages to prefetch from it here.
  211. //
  212. union {
  213. LARGE_INTEGER FileIndexNumber;
  214. ULONG MFTNumPagesToPrefetch;
  215. };
  216. //
  217. // This is the section record that we will setup and save in the
  218. // scenario file.
  219. //
  220. PF_SECTION_RECORD SectionRecord;
  221. //
  222. // File path for this section.
  223. //
  224. WCHAR *FilePath;
  225. //
  226. // List of page nodes belonging to this section.
  227. //
  228. LIST_ENTRY PageList;
  229. //
  230. // This is the index of the section in the new trace file when
  231. // ordered by first access [i.e. page fault].
  232. //
  233. ULONG NewSectionIndex;
  234. //
  235. // This is the index of the section in the original scenario file.
  236. //
  237. ULONG OrgSectionIndex;
  238. //
  239. // Link in the volume's list of section nodes.
  240. //
  241. LIST_ENTRY SectionVolumeLink;
  242. } PFSVC_SECTION_NODE, *PPFSVC_SECTION_NODE;
  243. //
  244. // This structure contains a path and is used with the path list below.
  245. //
  246. typedef struct _PFSVC_PATH {
  247. //
  248. // Link in the path list sorted by insertion order.
  249. //
  250. LIST_ENTRY InOrderLink;
  251. //
  252. // Link in the path list sorted lexically.
  253. //
  254. LIST_ENTRY SortedLink;
  255. //
  256. // Number of characters in the path excluding terminating NUL.
  257. //
  258. ULONG Length;
  259. //
  260. // NUL terminated path.
  261. //
  262. WCHAR Path[1];
  263. } PFSVC_PATH, *PPFSVC_PATH;
  264. //
  265. // This structure holds a list paths. You should manipulate the
  266. // list or walk through paths in it only using the PathList APIs
  267. // (e.g. GetNextPathInOrder).
  268. //
  269. //
  270. // Wrapper around path lists.
  271. //
  272. typedef struct _PFSVC_PATH_LIST {
  273. //
  274. // The list of paths sorted by insertion order.
  275. //
  276. LIST_ENTRY InOrderList;
  277. //
  278. // The list of paths sorted lexically.
  279. //
  280. LIST_ENTRY SortedList;
  281. //
  282. // If non NULL, we will make allocations for new entries from it
  283. // instead of hitting the heap.
  284. //
  285. struct _PFSVC_STRING_ALLOCATOR *Allocator;
  286. //
  287. // Number of paths in the list.
  288. //
  289. ULONG NumPaths;
  290. //
  291. // Total length of the paths in the list excluding NULs.
  292. //
  293. ULONG TotalLength;
  294. //
  295. // Whether list will be case sensitive or not.
  296. //
  297. BOOLEAN CaseSensitive;
  298. } PFSVC_PATH_LIST, *PPFSVC_PATH_LIST;
  299. //
  300. // This structure is used to divide sections in a scenario to
  301. // different disk volumes (i.e. c:, d:) they are on.
  302. //
  303. typedef struct _PFSVC_VOLUME_NODE {
  304. //
  305. // Link in the scenario's list of volume nodes.
  306. //
  307. LIST_ENTRY VolumeLink;
  308. //
  309. // Volume path and length in number of characters excluding NUL.
  310. //
  311. WCHAR *VolumePath;
  312. ULONG VolumePathLength;
  313. //
  314. // List of sections that are on this volume that will be prefetched.
  315. //
  316. LIST_ENTRY SectionList;
  317. ULONG NumSections;
  318. //
  319. // This is the total number of sections on this volume, including
  320. // those that won't be prefetched.
  321. //
  322. ULONG NumAllSections;
  323. //
  324. // List of directories accessed on this volume.
  325. //
  326. PFSVC_PATH_LIST DirectoryList;
  327. //
  328. // Serial Number/Creation time for this volume. This is retrieved
  329. // either from a new trace or from the existing scenario file
  330. // (both should match or the scenario file gets discarded.)
  331. //
  332. LARGE_INTEGER CreationTime;
  333. ULONG SerialNumber;
  334. //
  335. // Pointer to section node for the MFT for this volume (if there is one).
  336. //
  337. PPFSVC_SECTION_NODE MFTSectionNode;
  338. } PFSVC_VOLUME_NODE, *PPFSVC_VOLUME_NODE;
  339. //
  340. // Wrapper around page records.
  341. //
  342. typedef struct _PFSVC_PAGE_NODE {
  343. //
  344. // Link in the section node's list of pages.
  345. //
  346. LIST_ENTRY PageLink;
  347. //
  348. // Page record from previous scenario instructions or a new one
  349. // initialized for a trace log entry.
  350. //
  351. PF_PAGE_RECORD PageRecord;
  352. } PFSVC_PAGE_NODE, *PPFSVC_PAGE_NODE;
  353. //
  354. // This structure is used to make a single big allocation and give it away
  355. // in small chunks to be used as strings. It is very simple and will not reclaim
  356. // freed memory for future allocs. The whole allocation will be freed in cleanup.
  357. // There is no synchronization.
  358. //
  359. typedef struct _PFSVC_STRING_ALLOCATOR {
  360. //
  361. // Actual allocation to be divided up and given away in small chunks.
  362. //
  363. PCHAR Buffer;
  364. //
  365. // End of buffer. If FreePointer is equal to beyond this we can't give
  366. // away more from this buffer.
  367. //
  368. PCHAR BufferEnd;
  369. //
  370. // Pointer to start of free memory in Buffer.
  371. //
  372. PCHAR FreePointer;
  373. //
  374. // Number of times we had to hit the heap because we ran out of space
  375. // and the current outstanding such allocations.
  376. //
  377. ULONG MaxHeapAllocs;
  378. ULONG NumHeapAllocs;
  379. //
  380. // Size of the last allocation that was made from the buffer.
  381. //
  382. USHORT LastAllocationSize;
  383. //
  384. // Whether user has passed in Buffer (so we don't free it when
  385. // cleaning up.
  386. //
  387. ULONG UserSpecifiedBuffer:1;
  388. } PFSVC_STRING_ALLOCATOR, *PPFSVC_STRING_ALLOCATOR;
  389. //
  390. // This structure comes before allocations from the string allocator buffer.
  391. //
  392. typedef struct _PFSVC_STRING_ALLOCATION_HEADER {
  393. // ISSUE-2002/03/29-ScottMa -- Anonymous unions are no longer supported by
  394. // the compiler. They are a non-standard extension (see MSDN -- C4201).
  395. // There are two such unions/structs below.
  396. union {
  397. //
  398. // This structure contains the actual fields.
  399. //
  400. struct {
  401. //
  402. // Size of the preceding allocation.
  403. //
  404. USHORT PrecedingAllocationSize;
  405. //
  406. // Size of this allocation.
  407. //
  408. USHORT AllocationSize;
  409. };
  410. //
  411. // Require pointer alignment for this structure, so allocations
  412. // from the string allocator end up pointer aligned.
  413. //
  414. PVOID FieldToRequirePointerAlignment;
  415. };
  416. } PFSVC_STRING_ALLOCATION_HEADER, *PPFSVC_STRING_ALLOCATION_HEADER;
  417. //
  418. // This structure is used to make a single big allocation and give it away
  419. // to be used as page nodes, sections nodes etc in small chunks. It is very
  420. // simple and will not reclaim freed small chunks for future allocs. The whole
  421. // allocation will be freed in cleanup. The chunk size and max allocs to satisfy
  422. // is fixed at initialization. There is no synchronization.
  423. //
  424. typedef struct _PFSVC_CHUNK_ALLOCATOR {
  425. //
  426. // Actual allocation to be divided up and given away in small chunks.
  427. //
  428. PCHAR Buffer;
  429. //
  430. // End of buffer. If FreePointer is equal to beyond this we can't give
  431. // away more from this buffer.
  432. //
  433. PCHAR BufferEnd;
  434. //
  435. // Pointer to start of free memory in Buffer.
  436. //
  437. PCHAR FreePointer;
  438. //
  439. // How big each chunk will be in bytes.
  440. //
  441. ULONG ChunkSize;
  442. //
  443. // Number of times we had to hit the heap because we ran out of space
  444. // and the current outstanding such allocations.
  445. //
  446. ULONG MaxHeapAllocs;
  447. ULONG NumHeapAllocs;
  448. //
  449. // Whether user has passed in Buffer (so we don't free it when
  450. // cleaning up.
  451. //
  452. ULONG UserSpecifiedBuffer:1;
  453. } PFSVC_CHUNK_ALLOCATOR, *PPFSVC_CHUNK_ALLOCATOR;
  454. //
  455. // Wrapper around a scenario structure.
  456. //
  457. typedef struct _PFSVC_SCENARIO_INFO {
  458. //
  459. // Header information for the scenario instructions in preparation.
  460. //
  461. PF_SCENARIO_HEADER ScenHeader;
  462. //
  463. // Allocators used to make allocations for scenario processing efficient.
  464. //
  465. PVOID OneBigAllocation;
  466. PFSVC_CHUNK_ALLOCATOR SectionNodeAllocator;
  467. PFSVC_CHUNK_ALLOCATOR PageNodeAllocator;
  468. PFSVC_CHUNK_ALLOCATOR VolumeNodeAllocator;
  469. PFSVC_STRING_ALLOCATOR PathAllocator;
  470. //
  471. // Container for the sections in this scenario.
  472. //
  473. LIST_ENTRY SectionList;
  474. //
  475. // List of disk volumes that the scenario's sections are on. This
  476. // list is sorted lexically.
  477. //
  478. LIST_ENTRY VolumeList;
  479. //
  480. // Various statistics acquired from the trace information and used
  481. // in applying prefetch policy.
  482. //
  483. ULONG NewPages;
  484. ULONG HitPages;
  485. ULONG MissedOpportunityPages;
  486. ULONG IgnoredPages;
  487. ULONG PrefetchedPages;
  488. } PFSVC_SCENARIO_INFO, *PPFSVC_SCENARIO_INFO;
  489. //
  490. // This is a priority queue used for sorting section nodes by first
  491. // access.
  492. //
  493. typedef struct _PFSV_SECTNODE_PRIORITY_QUEUE {
  494. //
  495. // Think of this priority queue as a Head node and a binary sorted
  496. // tree at the right child of the Head node. The left child of the
  497. // Head node always stays NULL. If we need to add a new node
  498. // smaller than Head, the new node becames the new Head. This way
  499. // we always have binary sorted tree rooted at Head as well.
  500. //
  501. PPFSVC_SECTION_NODE Head;
  502. } PFSV_SECTNODE_PRIORITY_QUEUE, *PPFSV_SECTNODE_PRIORITY_QUEUE;
  503. //
  504. // A list of these may be used to convert the prefix of a path from NT
  505. // to DOS style. [e.g. \Device\HarddiskVolume1 to C:]
  506. //
  507. typedef struct _NTPATH_TRANSLATION_ENTRY {
  508. //
  509. // Link in a list of translation entries.
  510. //
  511. LIST_ENTRY Link;
  512. //
  513. // NT path prefix to convert and its length in number of
  514. // characters excluding NUL.
  515. //
  516. WCHAR *NtPrefix;
  517. ULONG NtPrefixLength;
  518. //
  519. // A DOS path prefix that the NT Path translates to. Note that
  520. // this not the only possible DOS name translation as a volume may
  521. // be mounted anywhere.
  522. //
  523. WCHAR *DosPrefix;
  524. ULONG DosPrefixLength;
  525. //
  526. // This is the volume string returned by FindNextVolume.
  527. //
  528. WCHAR *VolumeName;
  529. ULONG VolumeNameLength;
  530. } NTPATH_TRANSLATION_ENTRY, *PNTPATH_TRANSLATION_ENTRY;
  531. typedef LIST_ENTRY NTPATH_TRANSLATION_LIST;
  532. typedef NTPATH_TRANSLATION_LIST *PNTPATH_TRANSLATION_LIST;
  533. //
  534. // Define structure that wraps traces from the kernel.
  535. //
  536. typedef struct _PFSVC_TRACE_BUFFER {
  537. //
  538. // Traces are saved on the list via this link.
  539. //
  540. LIST_ENTRY TracesLink;
  541. //
  542. // The real trace from kernel starts here and extends for traces
  543. // size.
  544. //
  545. PF_TRACE_HEADER Trace;
  546. } PFSVC_TRACE_BUFFER, *PPFSVC_TRACE_BUFFER;
  547. //
  548. // Define the globals structure.
  549. //
  550. typedef struct _PFSVC_GLOBALS {
  551. //
  552. // Prefetch parameters. These won't be initialized when globals are
  553. // initialized and have to be explicitly acquired from the kernel.
  554. // Use PrefetchRoot below instead of RootDirPath in this structure.
  555. //
  556. PF_SYSTEM_PREFETCH_PARAMETERS Parameters;
  557. //
  558. // OS Version information.
  559. //
  560. OSVERSIONINFOEXW OsVersion;
  561. //
  562. // An array of path suffices to recognize files we don't want to prefetch
  563. // for boot. It is UPCASE and sorted lexically going from last character
  564. // to first.
  565. //
  566. WCHAR **FilesToIgnoreForBoot;
  567. ULONG NumFilesToIgnoreForBoot;
  568. ULONG *FileSuffixLengths;
  569. //
  570. // This manual reset event gets set when the prefetcher service is
  571. // asked to go away.
  572. //
  573. HANDLE TerminateServiceEvent;
  574. //
  575. // This is the list of traces acquired from the kernel that have
  576. // to be processed, number of them and the lock to protect the
  577. // list.
  578. //
  579. LIST_ENTRY Traces;
  580. ULONG NumTraces;
  581. HANDLE TracesLock;
  582. //
  583. // This auto-clearing event is set when new traces are put on the
  584. // list.
  585. //
  586. HANDLE NewTracesToProcessEvent;
  587. //
  588. // This auto-clearing event is set when we had max number of
  589. // queued traces and we process one. It signifies that we should
  590. // check for any traces we could not pick up because the queue was
  591. // maxed.
  592. //
  593. HANDLE CheckForMissedTracesEvent;
  594. //
  595. // This named manual-reset event is set to force the prefetcher
  596. // service to process the traces without waiting for an idle
  597. // system.
  598. //
  599. HANDLE OverrideIdleProcessingEvent;
  600. //
  601. // This named manual-reset event is set when processing of the
  602. // currently available traces are done.
  603. //
  604. HANDLE ProcessingCompleteEvent;
  605. //
  606. // This is the path to the directory where prefetch files are
  607. // kept and the lock to protect it.
  608. //
  609. WCHAR PrefetchRoot[MAX_PATH + 1];
  610. HANDLE PrefetchRootLock;
  611. //
  612. // Number of prefetch files in the prefetch directory. This is an estimate
  613. // (i.e. may not be exact) used to make sure the prefetch directory does
  614. // not grow too big.
  615. //
  616. ULONG NumPrefetchFiles;
  617. //
  618. // This is a registry handle to the data key under which some
  619. // prefetch service data is stored.
  620. //
  621. HKEY ServiceDataKey;
  622. //
  623. // This is the number of total traces we attempted to process.
  624. //
  625. ULONG NumTracesProcessed;
  626. //
  627. // This is the number of traces processed successfully.
  628. //
  629. ULONG NumTracesSuccessful;
  630. //
  631. // This is the last error code with which we failed processing a
  632. // trace.
  633. //
  634. DWORD LastTraceFailure;
  635. //
  636. // Did the defragger crash last time we ran it?
  637. //
  638. DWORD DefraggerErrorCode;
  639. //
  640. // Whether we are asked not to run the defragger in the registry.
  641. //
  642. DWORD DontRunDefragger;
  643. //
  644. // Pointer to path where CSC (client side caching) files are stored.
  645. //
  646. WCHAR *CSCRootPath;
  647. } PFSVC_GLOBALS, *PPFSVC_GLOBALS;
  648. //
  649. // This describes a worker function called when it is time for an idle
  650. // task to run.
  651. //
  652. typedef
  653. DWORD
  654. (*PFSVC_IDLE_TASK_WORKER_FUNCTION) (
  655. struct _PFSVC_IDLE_TASK *Task
  656. );
  657. //
  658. // This structure is used to keep context for a registered idle task.
  659. //
  660. typedef struct _PFSVC_IDLE_TASK {
  661. //
  662. // Parameters filled in by RegisterIdleTask call.
  663. //
  664. HANDLE ItHandle;
  665. HANDLE StartEvent;
  666. HANDLE StopEvent;
  667. //
  668. // Handle for the registered wait.
  669. //
  670. HANDLE WaitHandle;
  671. //
  672. // The registered callback function that will be called when the start
  673. // event is signaled.
  674. //
  675. WAITORTIMERCALLBACK Callback;
  676. //
  677. // If the common callback function is specified, it calls this function
  678. // to do the actual work.
  679. //
  680. PFSVC_IDLE_TASK_WORKER_FUNCTION DoWorkFunction;
  681. //
  682. // This is a manual reset event that will be set when the wait/callback
  683. // on the start event is fully unregistered.
  684. //
  685. HANDLE WaitUnregisteredEvent;
  686. //
  687. // This manual reset event gets reset when a callback starts running and
  688. // gets signaled when the callback stops running. Signaling of this event
  689. // is not protected so you can't purely rely on it. It is useful as a
  690. // shortcut.
  691. //
  692. HANDLE CallbackStoppedEvent;
  693. //
  694. // This manual reset event gets signaled when somebody starts unregistering.
  695. //
  696. HANDLE StartedUnregisteringEvent;
  697. //
  698. // This manual reset event gets signaled when somebody completes unregistering.
  699. //
  700. HANDLE CompletedUnregisteringEvent;
  701. //
  702. // The first one to interlocked set this from 0 to an integer is responsible
  703. // for unregistering the wait & task and cleaning up.
  704. //
  705. LONG Unregistering;
  706. //
  707. // This is interlocked set from 0 to an integer when a callback is running,
  708. // or when the main thread is unregistering.
  709. //
  710. LONG CallbackRunning;
  711. //
  712. // Whether this task is registered (i.e. and has to be unregistered.)
  713. //
  714. BOOLEAN Registered;
  715. //
  716. // Whether this task has been initialized, used as a sanity check.
  717. //
  718. BOOLEAN Initialized;
  719. } PFSVC_IDLE_TASK, *PPFSVC_IDLE_TASK;
  720. //
  721. // Values for the Unregistering field of PFSVC_IDLE_TASK.
  722. //
  723. typedef enum _PFSVC_TASK_UNREGISTERING_VALUES {
  724. PfSvcNotUnregisteringTask = 0,
  725. PfSvcUnregisteringTaskFromCallback,
  726. PfSvcUnregisteringTaskFromMainThread,
  727. PfSvcUnregisteringTaskMaxValue
  728. } PFSVC_TASK_UNREGISTERING_VALUES, *PPFSVC_TASK_UNREGISTERING_VALUES;
  729. //
  730. // Values for the CallbackRunning field of PFSVC_IDLE_TASK.
  731. //
  732. typedef enum _PFSVC_TASK_CALLBACKRUNNING_VALUES {
  733. PfSvcTaskCallbackNotRunning = 0,
  734. PfSvcTaskCallbackRunning,
  735. PfSvcTaskCallbackDisabled,
  736. PfSvcTaskCallbackMaxValue
  737. } PFSVC_TASK_CALLBACKRUNNING_VALUES, *PPFSVC_TASK_CALLBACKRUNNING_VALUES;
  738. //
  739. // Information on a scenario file's age, number of launches etc. used in
  740. // discarding old scenario files in the prefetch directory.
  741. //
  742. typedef struct _PFSVC_SCENARIO_AGE_INFO {
  743. //
  744. // Weight calculated based on the launch information. Larger weight is
  745. // better. We'd rather discard scenario with smaller weight.
  746. //
  747. ULONG Weight;
  748. //
  749. // Scenario file path.
  750. //
  751. WCHAR *FilePath;
  752. } PFSVC_SCENARIO_AGE_INFO, *PPFSVC_SCENARIO_AGE_INFO;
  753. //
  754. // This structure is used to enumerate through the scenario files
  755. // in the prefetch directory. None of the fields of this function
  756. // should be modified outside the file cursor routines.
  757. //
  758. typedef struct _PFSVC_SCENARIO_FILE_CURSOR {
  759. //
  760. // Data returned from FindFile calls for the current prefetch file.
  761. //
  762. WIN32_FIND_DATA FileData;
  763. //
  764. // The current prefetch file's full path.
  765. //
  766. WCHAR *FilePath;
  767. //
  768. // File name & path length in number of characters excluding NUL.
  769. //
  770. ULONG FileNameLength;
  771. ULONG FilePathLength;
  772. //
  773. // Index of the current file.
  774. //
  775. ULONG CurrentFileIdx;
  776. //
  777. // The fields below are used privately by the scenario file cursor
  778. // functions.
  779. //
  780. //
  781. // FindFile handle.
  782. //
  783. HANDLE FindFileHandle;
  784. //
  785. // Where we are looking for prefetch files.
  786. //
  787. WCHAR *PrefetchRoot;
  788. ULONG PrefetchRootLength;
  789. //
  790. // This is the maximum length string the allocated FilePath can store.
  791. //
  792. ULONG FilePathMaxLength;
  793. //
  794. // This is where the file name starts in the file path. The base of
  795. // the file path does not change (i.e. PrefetchRoot) and we copy
  796. // the new enumerated file name starting at FilePath+FileNameStart.
  797. //
  798. ULONG FileNameStart;
  799. } PFSVC_SCENARIO_FILE_CURSOR, *PPFSVC_SCENARIO_FILE_CURSOR;
  800. //
  801. // Return values from CompareSuffix.
  802. //
  803. typedef enum _PFSV_SUFFIX_COMPARISON_RESULT {
  804. PfSvSuffixIdentical,
  805. PfSvSuffixLongerThan,
  806. PfSvSuffixLessThan,
  807. PfSvSuffixGreaterThan
  808. } PFSV_SUFFIX_COMPARISON_RESULT, *PPFSV_SUFFIX_COMPARISON_RESULT;
  809. //
  810. // Return values from ComparePrefix.
  811. //
  812. typedef enum _PFSV_PREFIX_COMPARISON_RESULT {
  813. PfSvPrefixIdentical,
  814. PfSvPrefixLongerThan,
  815. PfSvPrefixLessThan,
  816. PfSvPrefixGreaterThan
  817. } PFSV_PREFIX_COMPARISON_RESULT, *PPFSV_PREFIX_COMPARISON_RESULT;
  818. //
  819. // Return values from SectionNodeComparisonRoutine.
  820. //
  821. typedef enum _PFSV_SECTION_NODE_COMPARISON_RESULT {
  822. PfSvSectNode1LessThanSectNode2 = -1,
  823. PfSvSectNode1EqualToSectNode2 = 0,
  824. PfSvSectNode1GreaterThanSectNode2 = 1,
  825. } PFSV_SECTION_NODE_COMPARISON_RESULT, *PPFSV_SECTION_NODE_COMPARISON_RESULT;
  826. //
  827. // Local function prototypes:
  828. //
  829. //
  830. // Exposed routines:
  831. //
  832. DWORD
  833. WINAPI
  834. PfSvcMainThread(
  835. VOID *Param
  836. );
  837. //
  838. // Internal service routines:
  839. //
  840. //
  841. // Thread routines:
  842. //
  843. DWORD
  844. WINAPI
  845. PfSvProcessTraceThread(
  846. VOID *Param
  847. );
  848. DWORD
  849. WINAPI
  850. PfSvPollShellReadyWorker(
  851. VOID *Param
  852. );
  853. //
  854. // Routines called by the main prefetcher thread.
  855. //
  856. DWORD
  857. PfSvGetRawTraces(
  858. VOID
  859. );
  860. DWORD
  861. PfSvInitializeGlobals(
  862. VOID
  863. );
  864. VOID
  865. PfSvCleanupGlobals(
  866. VOID
  867. );
  868. DWORD
  869. PfSvGetCSCRootPath (
  870. WCHAR *CSCRootPath,
  871. ULONG CSCRootPathMaxChars
  872. );
  873. DWORD
  874. PfSvGetDontRunDefragger(
  875. DWORD *DontRunDefragger
  876. );
  877. DWORD
  878. PfSvSetPrefetchParameters(
  879. PPF_SYSTEM_PREFETCH_PARAMETERS Parameters
  880. );
  881. DWORD
  882. PfSvQueryPrefetchParameters(
  883. PPF_SYSTEM_PREFETCH_PARAMETERS Parameters
  884. );
  885. DWORD
  886. PfSvInitializePrefetchDirectory(
  887. WCHAR *PathFromSystemRoot
  888. );
  889. DWORD
  890. PfSvCountFilesInDirectory(
  891. WCHAR *DirectoryPath,
  892. WCHAR *MatchExpression,
  893. PULONG NumFiles
  894. );
  895. //
  896. // Routines to process acquired traces:
  897. //
  898. DWORD
  899. PfSvProcessTrace(
  900. PPF_TRACE_HEADER Trace
  901. );
  902. VOID
  903. PfSvInitializeScenarioInfo (
  904. PPFSVC_SCENARIO_INFO ScenarioInfo,
  905. PPF_SCENARIO_ID ScenarioId,
  906. PF_SCENARIO_TYPE ScenarioType
  907. );
  908. VOID
  909. PfSvCleanupScenarioInfo(
  910. PPFSVC_SCENARIO_INFO ScenarioInfo
  911. );
  912. DWORD
  913. PfSvScenarioOpen (
  914. IN PWCHAR FilePath,
  915. IN PPF_SCENARIO_ID ScenarioId,
  916. IN PF_SCENARIO_TYPE ScenarioType,
  917. OUT PPF_SCENARIO_HEADER *Scenario
  918. );
  919. DWORD
  920. PfSvScenarioGetFilePath(
  921. OUT PWCHAR FilePath,
  922. IN ULONG FilePathMaxChars,
  923. IN PPF_SCENARIO_ID ScenarioId
  924. );
  925. DWORD
  926. PfSvScenarioInfoPreallocate(
  927. IN PPFSVC_SCENARIO_INFO ScenarioInfo,
  928. OPTIONAL IN PPF_SCENARIO_HEADER Scenario,
  929. IN PPF_TRACE_HEADER Trace
  930. );
  931. DWORD
  932. PfSvAddExistingScenarioInfo(
  933. PPFSVC_SCENARIO_INFO ScenarioInfo,
  934. PPF_SCENARIO_HEADER Scenario
  935. );
  936. DWORD
  937. PfSvVerifyVolumeMagics(
  938. PPFSVC_SCENARIO_INFO ScenarioInfo,
  939. PPF_TRACE_HEADER Trace
  940. );
  941. DWORD
  942. PfSvAddTraceInfo(
  943. PPFSVC_SCENARIO_INFO ScenarioInfo,
  944. PPF_TRACE_HEADER Trace
  945. );
  946. PPFSVC_SECTION_NODE
  947. PfSvGetSectionRecord(
  948. PPFSVC_SCENARIO_INFO ScenarioInfo,
  949. WCHAR *FilePath,
  950. ULONG FilePathLength
  951. );
  952. DWORD
  953. PfSvAddFaultInfoToSection(
  954. PPFSVC_SCENARIO_INFO ScenarioInfo,
  955. PPF_LOG_ENTRY LogEntry,
  956. PPFSVC_SECTION_NODE SectionNode
  957. );
  958. DWORD
  959. PfSvApplyPrefetchPolicy(
  960. PPFSVC_SCENARIO_INFO ScenarioInfo
  961. );
  962. ULONG
  963. PfSvGetNumTimesUsed(
  964. ULONG UsageHistory,
  965. ULONG UsageHistorySize
  966. );
  967. ULONG
  968. PfSvGetTraceEndIdx(
  969. PPF_TRACE_HEADER Trace
  970. );
  971. //
  972. // Routines to write updated scenario instructions to the scenario
  973. // file.
  974. //
  975. DWORD
  976. PfSvWriteScenario(
  977. PPFSVC_SCENARIO_INFO ScenarioInfo,
  978. PWCHAR ScenarioFilePath
  979. );
  980. DWORD
  981. PfSvPrepareScenarioDump(
  982. IN PPFSVC_SCENARIO_INFO ScenarioInfo,
  983. OUT PPF_SCENARIO_HEADER *ScenarioPtr
  984. );
  985. //
  986. // Routines to maintain the optimal disk layout file and update disk
  987. // layout.
  988. //
  989. DWORD
  990. PfSvUpdateOptimalLayout(
  991. PPFSVC_IDLE_TASK Task
  992. );
  993. DWORD
  994. PfSvUpdateLayout (
  995. PPFSVC_PATH_LIST CurrentLayout,
  996. PPFSVC_PATH_LIST OptimalLayout,
  997. PBOOLEAN LayoutChanged
  998. );
  999. DWORD
  1000. PfSvDetermineOptimalLayout (
  1001. PPFSVC_IDLE_TASK Task,
  1002. PPFSVC_PATH_LIST OptimalLayout,
  1003. BOOL *BootScenarioProcessed
  1004. );
  1005. DWORD
  1006. PfSvUpdateLayoutForScenario (
  1007. PPFSVC_PATH_LIST OptimalLayout,
  1008. WCHAR *ScenarioFilePath,
  1009. PNTPATH_TRANSLATION_LIST TranslationList,
  1010. PWCHAR *DosPathBuffer,
  1011. PULONG DosPathBufferSize
  1012. );
  1013. DWORD
  1014. PfSvReadLayout(
  1015. IN WCHAR *FilePath,
  1016. OUT PPFSVC_PATH_LIST Layout,
  1017. OUT FILETIME *LastWriteTime
  1018. );
  1019. DWORD
  1020. PfSvSaveLayout(
  1021. IN WCHAR *FilePath,
  1022. IN PPFSVC_PATH_LIST Layout,
  1023. OUT FILETIME *LastWriteTime
  1024. );
  1025. DWORD
  1026. PfSvGetLayoutFilePath(
  1027. PWCHAR *FilePathBuffer,
  1028. PULONG FilePathBufferSize
  1029. );
  1030. //
  1031. // Routines to defrag the disks once after setup when the system is idle.
  1032. //
  1033. DWORD
  1034. PfSvDefragDisks(
  1035. PPFSVC_IDLE_TASK Task
  1036. );
  1037. DWORD
  1038. PfSvLaunchDefragger(
  1039. PPFSVC_IDLE_TASK Task,
  1040. BOOLEAN ForLayoutOptimization,
  1041. PWCHAR TargetDrive
  1042. );
  1043. DWORD
  1044. PfSvGetBuildDefragStatusValueName (
  1045. OSVERSIONINFOEXW *OsVersion,
  1046. PWCHAR *ValueName
  1047. );
  1048. DWORD
  1049. PfSvSetBuildDefragStatus(
  1050. OSVERSIONINFOEXW *OsVersion,
  1051. PWCHAR BuildDefragStatus,
  1052. ULONG Size
  1053. );
  1054. DWORD
  1055. PfSvGetBuildDefragStatus(
  1056. OSVERSIONINFOEXW *OsVersion,
  1057. PWCHAR *BuildDefragStatus,
  1058. PULONG ReturnSize
  1059. );
  1060. //
  1061. // Routines to cleanup old scenario files in the prefetch directory.
  1062. //
  1063. DWORD
  1064. PfSvCleanupPrefetchDirectory(
  1065. PPFSVC_IDLE_TASK Task
  1066. );
  1067. int
  1068. __cdecl
  1069. PfSvCompareScenarioAgeInfo(
  1070. const void *Param1,
  1071. const void *Param2
  1072. );
  1073. //
  1074. // Routines to enumerate scenario files.
  1075. //
  1076. VOID
  1077. PfSvInitializeScenarioFileCursor (
  1078. PPFSVC_SCENARIO_FILE_CURSOR FileCursor
  1079. );
  1080. VOID
  1081. PfSvCleanupScenarioFileCursor(
  1082. PPFSVC_SCENARIO_FILE_CURSOR FileCursor
  1083. );
  1084. DWORD
  1085. PfSvStartScenarioFileCursor(
  1086. PPFSVC_SCENARIO_FILE_CURSOR FileCursor,
  1087. WCHAR *PrefetchRoot
  1088. );
  1089. DWORD
  1090. PfSvGetNextScenarioFileInfo(
  1091. PPFSVC_SCENARIO_FILE_CURSOR FileCursor
  1092. );
  1093. //
  1094. // File I/O utility routines.
  1095. //
  1096. DWORD
  1097. PfSvGetViewOfFile(
  1098. IN WCHAR *FilePath,
  1099. OUT PVOID *BasePointer,
  1100. OUT PULONG FileSize
  1101. );
  1102. DWORD
  1103. PfSvWriteBuffer(
  1104. PWCHAR FilePath,
  1105. PVOID Buffer,
  1106. ULONG Length
  1107. );
  1108. DWORD
  1109. PfSvGetLastWriteTime (
  1110. WCHAR *FilePath,
  1111. PFILETIME LastWriteTime
  1112. );
  1113. DWORD
  1114. PfSvReadLine (
  1115. FILE *File,
  1116. WCHAR **LineBuffer,
  1117. ULONG *LineBufferMaxChars,
  1118. ULONG *LineLength
  1119. );
  1120. DWORD
  1121. PfSvGetFileBasicInformation (
  1122. WCHAR *FilePath,
  1123. PFILE_BASIC_INFORMATION FileInformation
  1124. );
  1125. DWORD
  1126. PfSvGetFileIndexNumber(
  1127. WCHAR *FilePath,
  1128. PLARGE_INTEGER FileIndexNumber
  1129. );
  1130. //
  1131. // String utility routines.
  1132. //
  1133. PFSV_SUFFIX_COMPARISON_RESULT
  1134. PfSvCompareSuffix(
  1135. WCHAR *String,
  1136. ULONG StringLength,
  1137. WCHAR *Suffix,
  1138. ULONG SuffixLength,
  1139. BOOLEAN CaseSensitive
  1140. );
  1141. PFSV_PREFIX_COMPARISON_RESULT
  1142. PfSvComparePrefix(
  1143. WCHAR *String,
  1144. ULONG StringLength,
  1145. WCHAR *Prefix,
  1146. ULONG PrefixLength,
  1147. BOOLEAN CaseSensitive
  1148. );
  1149. VOID
  1150. FASTCALL
  1151. PfSvRemoveEndOfLineChars (
  1152. WCHAR *Line,
  1153. ULONG *LineLength
  1154. );
  1155. PWCHAR
  1156. PfSvcAnsiToUnicode(
  1157. PCHAR str
  1158. );
  1159. PCHAR
  1160. PfSvcUnicodeToAnsi(
  1161. PWCHAR wstr
  1162. );
  1163. VOID
  1164. PfSvcFreeString(
  1165. PVOID String
  1166. );
  1167. //
  1168. // Routines that deal with information in the registry.
  1169. //
  1170. DWORD
  1171. PfSvSaveStartInfo (
  1172. HKEY ServiceDataKey
  1173. );
  1174. DWORD
  1175. PfSvSaveExitInfo (
  1176. HKEY ServiceDataKey,
  1177. DWORD ExitCode
  1178. );
  1179. DWORD
  1180. PfSvSaveTraceProcessingStatistics (
  1181. HKEY ServiceDataKey
  1182. );
  1183. DWORD
  1184. PfSvGetLastDiskLayoutTime(
  1185. FILETIME *LastDiskLayoutTime
  1186. );
  1187. DWORD
  1188. PfSvSetLastDiskLayoutTime(
  1189. FILETIME *LastDiskLayoutTime
  1190. );
  1191. BOOLEAN
  1192. PfSvAllowedToRunDefragger(
  1193. BOOLEAN CheckRegistry
  1194. );
  1195. //
  1196. // Routines that deal with security.
  1197. //
  1198. BOOL
  1199. PfSvSetPrivilege(
  1200. HANDLE hToken,
  1201. LPCTSTR lpszPrivilege,
  1202. ULONG ulPrivilege,
  1203. BOOL bEnablePrivilege
  1204. );
  1205. DWORD
  1206. PfSvSetAdminOnlyPermissions(
  1207. WCHAR *ObjectPath,
  1208. HANDLE ObjectHandle,
  1209. SE_OBJECT_TYPE ObjectType
  1210. );
  1211. DWORD
  1212. PfSvGetPrefetchServiceThreadPrivileges (
  1213. VOID
  1214. );
  1215. //
  1216. // Routines that deal with volume node structures.
  1217. //
  1218. DWORD
  1219. PfSvCreateVolumeNode (
  1220. PPFSVC_SCENARIO_INFO ScenarioInfo,
  1221. WCHAR *VolumePath,
  1222. ULONG VolumePathLength,
  1223. PLARGE_INTEGER CreationTime,
  1224. ULONG SerialNumber
  1225. );
  1226. PPFSVC_VOLUME_NODE
  1227. PfSvGetVolumeNode (
  1228. PPFSVC_SCENARIO_INFO ScenarioInfo,
  1229. WCHAR *FilePath,
  1230. ULONG FilePathLength
  1231. );
  1232. VOID
  1233. PfSvCleanupVolumeNode(
  1234. PPFSVC_SCENARIO_INFO ScenarioInfo,
  1235. PPFSVC_VOLUME_NODE VolumeNode
  1236. );
  1237. DWORD
  1238. PfSvAddParentDirectoriesToList(
  1239. PPFSVC_PATH_LIST DirectoryList,
  1240. ULONG VolumePathLength,
  1241. WCHAR *FilePath,
  1242. ULONG FilePathLength
  1243. );
  1244. //
  1245. // Routines used to allocate / free section & page nodes etc. efficiently.
  1246. //
  1247. VOID
  1248. PfSvChunkAllocatorInitialize (
  1249. PPFSVC_CHUNK_ALLOCATOR Allocator
  1250. );
  1251. DWORD
  1252. PfSvChunkAllocatorStart (
  1253. PPFSVC_CHUNK_ALLOCATOR Allocator,
  1254. PVOID Buffer,
  1255. ULONG ChunkSize,
  1256. ULONG MaxChunks
  1257. );
  1258. PVOID
  1259. PfSvChunkAllocatorAllocate (
  1260. PPFSVC_CHUNK_ALLOCATOR Allocator
  1261. );
  1262. VOID
  1263. PfSvChunkAllocatorFree (
  1264. PPFSVC_CHUNK_ALLOCATOR Allocator,
  1265. PVOID Allocation
  1266. );
  1267. VOID
  1268. PfSvChunkAllocatorCleanup (
  1269. PPFSVC_CHUNK_ALLOCATOR Allocator
  1270. );
  1271. //
  1272. // Routines used to allocate / free file / directory / volume paths fast.
  1273. //
  1274. VOID
  1275. PfSvStringAllocatorInitialize (
  1276. PPFSVC_STRING_ALLOCATOR Allocator
  1277. );
  1278. DWORD
  1279. PfSvStringAllocatorStart (
  1280. PPFSVC_STRING_ALLOCATOR Allocator,
  1281. PVOID Buffer,
  1282. ULONG MaxSize
  1283. );
  1284. PVOID
  1285. PfSvStringAllocatorAllocate (
  1286. PPFSVC_STRING_ALLOCATOR Allocator,
  1287. ULONG NumBytes
  1288. );
  1289. VOID
  1290. PfSvStringAllocatorFree (
  1291. PPFSVC_STRING_ALLOCATOR Allocator,
  1292. PVOID Allocation
  1293. );
  1294. VOID
  1295. PfSvStringAllocatorCleanup (
  1296. PPFSVC_STRING_ALLOCATOR Allocator
  1297. );
  1298. //
  1299. // Routines that deal with section node structures.
  1300. //
  1301. VOID
  1302. PfSvCleanupSectionNode(
  1303. PPFSVC_SCENARIO_INFO ScenarioInfo,
  1304. PPFSVC_SECTION_NODE SectionNode
  1305. );
  1306. //
  1307. // Routines used to sort scenario's section nodes.
  1308. //
  1309. DWORD
  1310. PfSvSortSectionNodesByFirstAccess(
  1311. PLIST_ENTRY SectionNodeList
  1312. );
  1313. PFSV_SECTION_NODE_COMPARISON_RESULT
  1314. FASTCALL
  1315. PfSvSectionNodeComparisonRoutine(
  1316. PPFSVC_SECTION_NODE Element1,
  1317. PPFSVC_SECTION_NODE Element2
  1318. );
  1319. //
  1320. // Routines that implement a priority queue used to sort section nodes
  1321. // for a scenario.
  1322. //
  1323. VOID
  1324. PfSvInitializeSectNodePriorityQueue(
  1325. PPFSV_SECTNODE_PRIORITY_QUEUE PriorityQueue
  1326. );
  1327. VOID
  1328. PfSvInsertSectNodePriorityQueue(
  1329. PPFSV_SECTNODE_PRIORITY_QUEUE PriorityQueue,
  1330. PPFSVC_SECTION_NODE NewElement
  1331. );
  1332. PPFSVC_SECTION_NODE
  1333. PfSvRemoveMinSectNodePriorityQueue(
  1334. PPFSV_SECTNODE_PRIORITY_QUEUE PriorityQueue
  1335. );
  1336. //
  1337. // Implementation of the Nt path to Dos path translation API.
  1338. //
  1339. DWORD
  1340. PfSvBuildNtPathTranslationList(
  1341. PNTPATH_TRANSLATION_LIST *NtPathTranslationList
  1342. );
  1343. VOID
  1344. PfSvFreeNtPathTranslationList(
  1345. PNTPATH_TRANSLATION_LIST TranslationList
  1346. );
  1347. DWORD
  1348. PfSvTranslateNtPath(
  1349. PNTPATH_TRANSLATION_LIST TranslationList,
  1350. WCHAR *NtPath,
  1351. ULONG NtPathLength,
  1352. PWCHAR *DosPathBuffer,
  1353. PULONG DosPathBufferSize
  1354. );
  1355. //
  1356. // Path list API.
  1357. //
  1358. VOID
  1359. PfSvInitializePathList(
  1360. PPFSVC_PATH_LIST PathList,
  1361. PPFSVC_STRING_ALLOCATOR PathAllocator,
  1362. BOOLEAN CaseSensitive
  1363. );
  1364. VOID
  1365. PfSvCleanupPathList(
  1366. PPFSVC_PATH_LIST PathList
  1367. );
  1368. BOOLEAN
  1369. PfSvIsInPathList(
  1370. PPFSVC_PATH_LIST PathList,
  1371. WCHAR *Path,
  1372. ULONG PathLength
  1373. );
  1374. DWORD
  1375. PfSvAddToPathList(
  1376. PPFSVC_PATH_LIST PathList,
  1377. WCHAR *Path,
  1378. ULONG PathLength
  1379. );
  1380. PPFSVC_PATH
  1381. PfSvGetNextPathSorted (
  1382. PPFSVC_PATH_LIST PathList,
  1383. PPFSVC_PATH CurrentPath
  1384. );
  1385. PPFSVC_PATH
  1386. PfSvGetNextPathInOrder (
  1387. PPFSVC_PATH_LIST PathList,
  1388. PPFSVC_PATH CurrentPath
  1389. );
  1390. //
  1391. // Routines to build the list of files accessed by the boot loader.
  1392. //
  1393. DWORD
  1394. PfSvBuildBootLoaderFilesList (
  1395. PPFSVC_PATH_LIST PathList
  1396. );
  1397. ULONG
  1398. PfVerifyImageImportTable (
  1399. IN PVOID BaseAddress,
  1400. IN ULONG MappingSize,
  1401. IN BOOLEAN MappedAsImage
  1402. );
  1403. DWORD
  1404. PfSvAddBootImageAndImportsToList(
  1405. PPFSVC_PATH_LIST PathList,
  1406. WCHAR *FilePath,
  1407. ULONG FilePathLength
  1408. );
  1409. DWORD
  1410. PfSvLocateBootServiceFile(
  1411. IN WCHAR *FileName,
  1412. IN ULONG FileNameLength,
  1413. OUT WCHAR *FullPathBuffer,
  1414. IN ULONG FullPathBufferLength,
  1415. OUT PULONG RequiredLength
  1416. );
  1417. DWORD
  1418. PfSvGetBootServiceFullPath(
  1419. IN WCHAR *ServiceName,
  1420. IN WCHAR *BinaryPathName,
  1421. OUT WCHAR *FullPathBuffer,
  1422. IN ULONG FullPathBufferLength,
  1423. OUT PULONG RequiredLength
  1424. );
  1425. DWORD
  1426. PfSvGetBootLoaderNlsFileNames (
  1427. PPFSVC_PATH_LIST PathList
  1428. );
  1429. DWORD
  1430. PfSvLocateNlsFile(
  1431. WCHAR *FileName,
  1432. WCHAR *FilePathBuffer,
  1433. ULONG FilePathBufferLength,
  1434. ULONG *RequiredLength
  1435. );
  1436. DWORD
  1437. PfSvQueryNlsFileName (
  1438. HKEY Key,
  1439. WCHAR *ValueName,
  1440. WCHAR *FileNameBuffer,
  1441. ULONG FileNameBufferSize,
  1442. ULONG *RequiredSize
  1443. );
  1444. //
  1445. // Routines to manage / run idle tasks.
  1446. //
  1447. VOID
  1448. PfSvInitializeTask (
  1449. PPFSVC_IDLE_TASK Task
  1450. );
  1451. DWORD
  1452. PfSvRegisterTask (
  1453. PPFSVC_IDLE_TASK Task,
  1454. IT_IDLE_TASK_ID TaskId,
  1455. WAITORTIMERCALLBACK Callback,
  1456. PFSVC_IDLE_TASK_WORKER_FUNCTION DoWorkFunction
  1457. );
  1458. DWORD
  1459. PfSvUnregisterTask (
  1460. PPFSVC_IDLE_TASK Task,
  1461. BOOLEAN CalledFromCallback
  1462. );
  1463. VOID
  1464. PfSvCleanupTask (
  1465. PPFSVC_IDLE_TASK Task
  1466. );
  1467. BOOL
  1468. PfSvStartTaskCallback(
  1469. PPFSVC_IDLE_TASK Task
  1470. );
  1471. VOID
  1472. PfSvStopTaskCallback(
  1473. PPFSVC_IDLE_TASK Task
  1474. );
  1475. VOID
  1476. CALLBACK
  1477. PfSvCommonTaskCallback(
  1478. PVOID lpParameter,
  1479. BOOLEAN TimerOrWaitFired
  1480. );
  1481. DWORD
  1482. PfSvContinueRunningTask(
  1483. PPFSVC_IDLE_TASK Task
  1484. );
  1485. //
  1486. // ProcessIdleTasks notify routine and its dependencies.
  1487. //
  1488. VOID
  1489. PfSvProcessIdleTasksCallback(
  1490. VOID
  1491. );
  1492. DWORD
  1493. PfSvForceWMIProcessIdleTasks(
  1494. VOID
  1495. );
  1496. BOOL
  1497. PfSvWaitForServiceToStart (
  1498. LPTSTR ServiceName,
  1499. DWORD MaxWait
  1500. );
  1501. //
  1502. // Wrappers around verify routines.
  1503. //
  1504. BOOLEAN
  1505. PfSvVerifyScenarioBuffer(
  1506. PPF_SCENARIO_HEADER Scenario,
  1507. ULONG BufferSize,
  1508. PULONG FailedCheck
  1509. );
  1510. //
  1511. // Debug definitions.
  1512. //
  1513. #if DBG
  1514. #ifndef PFSVC_DBG
  1515. #define PFSVC_DBG
  1516. #endif // !PFSVC_DBG
  1517. #endif // DBG
  1518. #ifdef PFSVC_DBG
  1519. //
  1520. // Define the component ID we use.
  1521. //
  1522. #define PFID DPFLTR_PREFETCHER_ID
  1523. //
  1524. // Define DbgPrintEx levels.
  1525. //
  1526. #define PFERR DPFLTR_ERROR_LEVEL
  1527. #define PFWARN DPFLTR_WARNING_LEVEL
  1528. #define PFTRC DPFLTR_TRACE_LEVEL
  1529. #define PFINFO DPFLTR_INFO_LEVEL
  1530. //
  1531. // DbgPrintEx levels 4 - 19 are reserved for the kernel mode component.
  1532. //
  1533. #define PFSTRC 20
  1534. #define PFWAIT 21
  1535. #define PFLOCK 22
  1536. #define PFPATH 23
  1537. #define PFNTRC 24
  1538. #define PFTASK 25
  1539. //
  1540. // This may help you determine what to set the DbgPrintEx mask.
  1541. //
  1542. // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
  1543. // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  1544. // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  1545. //
  1546. NTSYSAPI
  1547. VOID
  1548. NTAPI
  1549. RtlAssert(
  1550. PVOID FailedAssertion,
  1551. PVOID FileName,
  1552. ULONG LineNumber,
  1553. PCHAR Message
  1554. );
  1555. #define DBGPR(x) DbgPrintEx x
  1556. #define PFSVC_ASSERT(x) if (!(x)) RtlAssert(#x, __FILE__, __LINE__, NULL )
  1557. //
  1558. // Variables used when saving traces acquired from the kernel. The
  1559. // traces are saved in the prefetch directory by appending the trace
  1560. // number % max number of saved traces to the base trace name.
  1561. //
  1562. WCHAR *PfSvcDbgTraceBaseName = L"PrefetchTrace";
  1563. LONG PfSvcDbgTraceNumber = 0;
  1564. LONG PfSvcDbgMaxNumSavedTraces = 20;
  1565. #else // PFSVC_DBG
  1566. #define DBGPR(x)
  1567. #define PFSVC_ASSERT(x)
  1568. #endif // PFSVC_DBG
  1569. #endif // _PFSVC_H_