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.

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