#include #include #include #include #include // Registry location for configuration settings #define CACHESVC_REG_KEY_LOC L"SYSTEM\\CurrentControlSet\\Services\\DynCache\\Parameters" // List of notifications for the service #define INTERNAL_WAKEUP 0 // Internal wake up event (for pause/resume/stop) #define REG_CHANGE_NOTIFICATION 1 // Registry settings were changed #define LOW_MEMORY_NOTIFICATION 2 // Available memory is below threshold, backoff cache usage #define MAX_NOTIFICATIONS 3 // Total number of notifications // One node of a linked list of counters for a process. // Each instance of a process will have one counter instance. // For example, if you have three instances of notepad, you'll have 3 counter instances. One for each process' working set size. typedef struct _COUNTER_INSTANCE { PDH_HCOUNTER hCounter; // Handle to a counter for this process's working set size _COUNTER_INSTANCE *Next; // Pointer to next counter instance } COUNTER_INSTANCE, *PCOUNTER_INSTANCE; // This is an entry for a process that the system cache will back off from typedef struct _PROCESS_ENTRY { LPWSTR wszImageName; // The process's image file name (defined in the registry) size_t WorkingSetSizeBytes; // Size of the working set in bytes for all instances of this process size_t AdditionalBackoffBytes; // Size in bytes of additional back off (slack space) (defined in the registry) LPWSTR wszAdditionalBackOffCounter; // Additional counter to backoff from (defined in the registry) size_t AdditionalCounterUnits; // Additional counter's units. Used to scale the value to bytes. PDH_HCOUNTER hAdditionalCounter; // Handle to the additional counter PCOUNTER_INSTANCE pCounter; // Pointer to the first counter instance for this process _PROCESS_ENTRY *Next; // Pointer to the next process entry } PROCESS_ENTRY, *PPROCESS_ENTRY; // Prototypes // Main function void DynCacheMain(DWORD dwArgc, LPWSTR *lpwszArgv); // Set the cache limits void LimitCache( size_t MaxCacheSize, size_t MinCacheSize ); // Service cleanup void SvcCleanup( DWORD dwStatus ); // Functions for being a service void ServiceCtrlHandler (DWORD dwControlCode); void ResumeService(); void PauseService(); void StopService(); BOOL SendStatusToSCM( DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint); #ifdef DBG // Used in debug builds to output logging messages void DebugMessage(LPWSTR wszPrintString, ... ); void DebugError(DWORD dwError); #else // No logging occurs in retail builds #define DebugMessage(x, ...) #define DebugError(x) #endif