|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
diskperf.c
Abstract:
Program to display and/or update the current value of the Diskperf driver startup value
Author:
Bob Watson (a-robw) 4 Dec 92
Revision History:
--*/ #include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntconfig.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <regstr.h> // for REGSTR_VAL_UPPERFILTERS
#include <tchar.h>
#include <locale.h>
#include "diskperf.h" // include text string id constancts
#include <ntdddisk.h>
#include <mountmgr.h>
LANGID WINAPI MySetThreadUILanguage( WORD wReserved);
#define SWITCH_CHAR '-' // is there a system call to get this?
#define ENABLE_CHAR 'Y' // command will be upcased
#define DISABLE_CHAR 'N'
#define ENHANCED_CHAR 'E'
#define LOCAL_CHANGE 2 // number of commands in a local change command
#define REMOTE_CHANGE 3 // number of commands in a remote change command
//
// note these values are arbitrarily based on the whims of the people
// developing the disk drive drivers that belong to the "Filter" group.
//
#define TAG_NORMAL 4 // diskperf starts AFTER ftdisk
#define TAG_ENHANCED 2 // diskperf starts BEFORE ftdisk
#define IRP_STACK_ENABLED 5 // size of IRP stack when diskperf is enabled
#define IRP_STACK_DISABLED 4 // size of IRP stack when diskperf is enabled
#define IRP_STACK_DEFAULT 8 // default IRP stack size in W2K
#define IRP_STACK_NODISKPERF 7
#define DISKPERF_SERVICE_NAME TEXT("DiskPerf")
LPCTSTR lpwszDiskPerfKey = TEXT("SYSTEM\\CurrentControlSet\\Services\\Diskperf"); LPCTSTR lpwszIOSystemKey = TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\I/O System"); LPCTSTR lpwszOsVersionKey = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"); LPCTSTR lpwszBuildNumber = TEXT("CurrentBuildNumber"); LPCTSTR lpwszOsVersion = TEXT("CurrentVersion");
#define ENABLE_DISKDRIVE 0x0001
#define ENABLE_VOLUME 0x0002
#define ENABLE_PERMANENT 0x0004
#define ENABLE_PERMANENT_IOCTL 0x0008
LPCTSTR lpwszDiskDriveKey = TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E967-E325-11CE-BFC1-08002BE10318}"); LPCTSTR lpwszVolumeKey = TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{71A27CDD-812A-11D0-BEC7-08002BE2092F}");
LPCTSTR lpwszPartmgrKey = TEXT("SYSTEM\\CurrentControlSet\\Services\\Partmgr"); LPCTSTR lpwszEnableCounterValue = TEXT("EnableCounterForIoctl");
ULONG OpenRegKeys( IN LPCTSTR lpszMachine, OUT PHKEY hRegistry, OUT PHKEY hDiskKey, OUT PHKEY hVolumeKey, OUT PHKEY hServiceKey );
ULONG SetFilter( IN HKEY hKey, IN LPTSTR strFilterString, IN DWORD dwSize );
ULONG GetFilter( IN HKEY hKey, OUT LPTSTR strFilterString, IN DWORD dwSize );
ULONG CheckFilter( IN TCHAR *Buffer );
ULONG GetEnableFlag( IN HKEY hDiskKey, IN HKEY hVolumeKey );
ULONG AddToFilter( IN HKEY hKey );
ULONG RemoveFromFilter( IN HKEY hKey );
void PrintStatus( IN BOOL bCurrent, IN ULONG EnableFlag, IN LPCTSTR cMachineName );
int __cdecl Dp_wprintf( const wchar_t *format, ... );
int __cdecl Dp_fwprintf( FILE *str, const wchar_t *format, ... );
int __cdecl Dp_vfwprintf( FILE *str, const wchar_t *format, va_list argptr );
BOOL IsBeyondW2K( IN LPCTSTR lpszMachine, OUT PDWORD EnableCounter);
ULONG EnableForIoctl( IN LPWSTR lpszMachineName );
ULONG DisableForIoctl( IN LPWSTR lpszMachineName, IN ULONG Request );
#if DBG
void DbgPrintMultiSz( TCHAR *String, ULONG Size ); #endif
#define REG_TO_DP_INDEX(reg_idx) (DP_LOAD_STATUS_BASE + (\
(reg_idx == SERVICE_BOOT_START) ? DP_BOOT_START : \ (reg_idx == SERVICE_SYSTEM_START) ? DP_SYSTEM_START : \ (reg_idx == SERVICE_AUTO_START) ? DP_AUTO_START : \ (reg_idx == SERVICE_DEMAND_START) ? DP_DEMAND_START : \ (reg_idx == SERVICE_DISABLED) ? DP_NEVER_START : DP_UNDEFINED))
#define MAX_MACHINE_NAME_LEN 32
// command line arguments
#define CMD_SHOW_LOCAL_STATUS 1
#define CMD_DO_COMMAND 2
#define ArgIsSystem(arg) (*(arg) == '\\' ? TRUE : FALSE)
//
// global buffer for help text display strings
//
#define DISP_BUFF_LEN 256
#define NUM_STRING_BUFFS 2
LPCTSTR BlankString = TEXT(" "); LPCTSTR StartKey = TEXT("Start"); LPCTSTR TagKey = TEXT("Tag"); LPCTSTR EmptyString = TEXT(""); LPCTSTR LargeIrps = TEXT("LargeIrpStackLocations");
HINSTANCE hMod = NULL; DWORD dwLastError;
LPCTSTR GetStringResource ( UINT wStringId ) { static TCHAR DisplayStringBuffer[NUM_STRING_BUFFS][DISP_BUFF_LEN]; static DWORD dwBuffIndex; LPTSTR szReturnBuffer;
dwBuffIndex++; dwBuffIndex %= NUM_STRING_BUFFS; szReturnBuffer = (LPTSTR)&DisplayStringBuffer[dwBuffIndex][0];
if (!hMod) { hMod = (HINSTANCE)GetModuleHandle(NULL); // get instance ID of this module;
}
if (hMod) { if ((LoadString(hMod, wStringId, szReturnBuffer, DISP_BUFF_LEN)) > 0) { return (LPCTSTR)szReturnBuffer; } else { dwLastError = GetLastError(); return EmptyString; } } else { return EmptyString; } } LPCTSTR GetFormatResource ( UINT wStringId ) { static TCHAR TextFormat[DISP_BUFF_LEN];
if (!hMod) { hMod = (HINSTANCE)GetModuleHandle(NULL); // get instance ID of this module;
}
if (hMod) { if ((LoadString(hMod, wStringId, TextFormat, DISP_BUFF_LEN)) > 0) { return (LPCTSTR)&TextFormat[0]; } else { dwLastError = GetLastError(); return BlankString; } } else { return BlankString; } }
VOID DisplayChangeCmd ( ) { UINT wID; TCHAR OemDisplayStringBuffer[DISP_BUFF_LEN * 2]; TCHAR DisplayStringBuffer[DISP_BUFF_LEN];
if (hMod) { if ((LoadString(hMod, DP_TEXT_FORMAT, DisplayStringBuffer, DISP_BUFF_LEN)) > 0) { for (wID=DP_CMD_HELP_START; wID <= DP_CMD_HELP_END; wID++) { if ((LoadString(hMod, wID, DisplayStringBuffer, DISP_BUFF_LEN)) > 0) { Dp_wprintf(DisplayStringBuffer); } } } } } VOID DisplayCmdHelp( ) { UINT wID; TCHAR OemDisplayStringBuffer[DISP_BUFF_LEN * 2]; TCHAR DisplayStringBuffer[DISP_BUFF_LEN];
if (hMod) { if ((LoadString(hMod, DP_TEXT_FORMAT, DisplayStringBuffer, DISP_BUFF_LEN)) > 0) { for (wID=DP_HELP_TEXT_START; wID <= DP_HELP_TEXT_END; wID++) { if ((LoadString(hMod, wID, DisplayStringBuffer, DISP_BUFF_LEN)) > 0) { Dp_wprintf(DisplayStringBuffer); } } } }
DisplayChangeCmd(); }
ULONG DisplayStatus ( LPTSTR lpszMachine ) { ULONG Status; HKEY hRegistry; HKEY hDiskPerfKey; HKEY hDiskKey; HKEY hVolumeKey; DWORD dwValue, dwValueSize, dwTag; TCHAR OemDisplayStringBuffer[DISP_BUFF_LEN * 2];
TCHAR cMachineName[MAX_MACHINE_NAME_LEN]; PTCHAR pThisWideChar; PTCHAR pThisChar; INT iCharCount; DWORD EnableCounter;
pThisChar = lpszMachine; pThisWideChar = cMachineName; iCharCount = 0;
if (pThisChar) { // if machine is not NULL, then copy
while (*pThisChar) { *pThisWideChar++ = (TCHAR)(*pThisChar++); if (++iCharCount >= MAX_MACHINE_NAME_LEN) break; } *pThisWideChar = 0; }
if (!lpszMachine) { lstrcpy(cMachineName, GetStringResource(DP_THIS_SYSTEM)); }
if (IsBeyondW2K(lpszMachine, &EnableCounter)) { if (EnableCounter) { PrintStatus(TRUE, ENABLE_PERMANENT_IOCTL, cMachineName); } else { PrintStatus(TRUE, ENABLE_PERMANENT, cMachineName); } return ERROR_SUCCESS; }
Status = OpenRegKeys( lpszMachine, &hRegistry, &hDiskKey, &hVolumeKey, &hDiskPerfKey);
if (Status != ERROR_SUCCESS) { #if DBG
fprintf(stderr, "DisplayStatus: Cannot open HKLM on target machine: %d\n", Status); #endif
Dp_wprintf(GetFormatResource(DP_UNABLE_READ_REGISTRY)); return Status; }
dwTag = GetEnableFlag(hDiskKey, hVolumeKey); dwValue = (dwTag == 0) ? SERVICE_DISABLED : SERVICE_BOOT_START; dwValueSize = sizeof(dwValue); Status = RegQueryValueEx ( hDiskPerfKey, StartKey, NULL, NULL, (LPBYTE)&dwValue, &dwValueSize);
if (Status != ERROR_SUCCESS) { Dp_wprintf(GetFormatResource(DP_UNABLE_READ_START)); goto DisplayStatusCleanup; }
PrintStatus(TRUE, dwTag, cMachineName);
DisplayStatusCleanup: RegCloseKey(hDiskKey); RegCloseKey(hVolumeKey); RegCloseKey(hDiskPerfKey); RegCloseKey(hRegistry);
if (Status != ERROR_SUCCESS) { Dp_wprintf(GetFormatResource(DP_STATUS_FORMAT), Status);
} return Status; }
ULONG DoChangeCommand ( LPTSTR lpszCommand, LPTSTR lpszMachine ) { // connect to registry on local machine with read/write access
ULONG Status; HKEY hRegistry; HKEY hDiskPerfKey; HKEY hDiskKey; HKEY hVolumeKey; DWORD dwValue, dwValueSize, dwOrigValue, dwTag, dwOrigTag;
TCHAR cMachineName[MAX_MACHINE_NAME_LEN]; PTCHAR pThisWideChar; PTCHAR pThisChar; INT iCharCount; PTCHAR pCmdChar;
TCHAR OemDisplayStringBuffer[DISP_BUFF_LEN * 2];
HKEY hIOSystemKey; DWORD dwDisposition; DWORD dwIrpValue; ULONG EnableRequest, DisableRequest; ULONG EnableFlag, EndFlag = 0; BOOL bModified, bIrpStackReg; LONG nIrpStack, nIrpStackReg, nIncrement; DWORD EnableCounter;
// check command to see if it's valid
_tcsupr (lpszCommand);
pCmdChar = lpszCommand; dwValue = 0; EnableRequest = DisableRequest = 0;
if (*pCmdChar++ == SWITCH_CHAR ) { if (!_tcscmp(pCmdChar, _T("Y")) || !_tcscmp(pCmdChar, _T("YA")) || !_tcscmp(pCmdChar, _T("YALL"))) { EnableRequest = ENABLE_DISKDRIVE | ENABLE_VOLUME; } else if (!_tcscmp(pCmdChar, _T("N")) || !_tcscmp(pCmdChar, _T("NA")) || !_tcscmp(pCmdChar, _T("NALL")) ) { DisableRequest = ENABLE_DISKDRIVE | ENABLE_VOLUME; } else if (!_tcscmp(pCmdChar, _T("YD")) || !_tcscmp(pCmdChar, _T("YDISK")) ) { EnableRequest = ENABLE_DISKDRIVE; } else if (!_tcscmp(pCmdChar, _T("YV")) || !_tcscmp(pCmdChar, _T("YVOLUME")) ) { EnableRequest = ENABLE_VOLUME; } else if (!_tcscmp(pCmdChar, _T("ND")) || !_tcscmp(pCmdChar, _T("NDISK")) ) { DisableRequest = ENABLE_DISKDRIVE; } else if (!_tcscmp(pCmdChar, _T("NV")) || !_tcscmp(pCmdChar, _T("NVOLUME")) ) { DisableRequest = ENABLE_VOLUME; } else { DisplayCmdHelp(); return ERROR_SUCCESS; } } else { DisplayChangeCmd(); return ERROR_SUCCESS; }
// if command OK then convert machine to wide string for connection
pThisChar = lpszMachine; pThisWideChar = cMachineName; iCharCount = 0;
if (pThisChar) { while (*pThisChar) { *pThisWideChar++ = (TCHAR)(*pThisChar++); if (++iCharCount >= MAX_MACHINE_NAME_LEN) break; } *pThisWideChar = 0; // null terminate
}
if (!lpszMachine) { lstrcpy (cMachineName, GetStringResource(DP_THIS_SYSTEM)); }
if (IsBeyondW2K(lpszMachine, &EnableCounter)) { if (EnableRequest != 0) { EnableForIoctl(lpszMachine); PrintStatus(TRUE, ENABLE_PERMANENT_IOCTL, cMachineName); } else if (DisableRequest != 0) { DisableForIoctl(lpszMachine, DisableRequest); PrintStatus(TRUE, ENABLE_PERMANENT, cMachineName); } return ERROR_SUCCESS; }
// connect to registry
Status = OpenRegKeys( lpszMachine, &hRegistry, &hDiskKey, &hVolumeKey, &hDiskPerfKey);
if (Status != ERROR_SUCCESS) { #if DBG
fprintf(stderr, "DoChangeCommand: Cannot connect to registry: Status=%d\n", Status); #endif
Dp_wprintf(GetFormatResource(DP_UNABLE_READ_REGISTRY)); return Status; }
hIOSystemKey = NULL; nIrpStackReg = 0; bIrpStackReg = FALSE; // no registry key prior to this
Status = RegCreateKeyEx ( hRegistry, lpwszIOSystemKey, 0L, //Reserved
NULL, 0L, // no special options
KEY_WRITE | KEY_READ, // desired access
NULL, // default security
&hIOSystemKey, &dwDisposition); if (Status != ERROR_SUCCESS) { if ((Status == ERROR_ALREADY_EXISTS) && (dwDisposition == REG_OPENED_EXISTING_KEY)) { // then this key is already in the registry so this is OK
Status = ERROR_SUCCESS; } else { Dp_wprintf(GetFormatResource(DP_UNABLE_READ_REGISTRY)); goto DoChangeCommandCleanup; } } if ( (Status == ERROR_SUCCESS) && (dwDisposition == REG_OPENED_EXISTING_KEY)) { DWORD dwSize; dwSize = sizeof(DWORD);
Status = RegQueryValueEx ( hIOSystemKey, LargeIrps, 0L, NULL, (LPBYTE)&dwIrpValue, &dwSize); if (Status == ERROR_SUCCESS) { #if DBG
fprintf(stderr, "Registry LargeIrpStack=%d\n", dwIrpValue); #endif
nIrpStackReg = dwIrpValue; bIrpStackReg = TRUE; } }
EnableFlag = GetEnableFlag(hDiskKey, hVolumeKey); #if DBG
fprintf(stderr, "DoChangeCommand: EnableFlag is %x\n", EnableFlag); #endif
bModified = FALSE;
nIncrement = 0; if ( (EnableRequest & ENABLE_DISKDRIVE) && !(EnableFlag & ENABLE_DISKDRIVE) ) { // Turn on filter for disk drives
if (AddToFilter(hDiskKey) == ERROR_SUCCESS) { bModified = TRUE; nIncrement++; } } if ( (EnableRequest & ENABLE_VOLUME) && !(EnableFlag & ENABLE_VOLUME) ) { // Turn on filter for volumes
if (AddToFilter(hVolumeKey) == ERROR_SUCCESS) { bModified = TRUE; nIncrement++; } } if ( (DisableRequest & ENABLE_DISKDRIVE) && (EnableFlag & ENABLE_DISKDRIVE) ) { // Turn off filter for disk drives
if (RemoveFromFilter(hDiskKey) == ERROR_SUCCESS) { bModified = TRUE; nIncrement--; } } if ( (DisableRequest & ENABLE_VOLUME) && (EnableFlag & ENABLE_VOLUME) ) { // Turn off filter for volumes
if (RemoveFromFilter(hVolumeKey) == ERROR_SUCCESS) { bModified = TRUE; nIncrement--; } }
nIrpStack = 0; EndFlag = GetEnableFlag(hDiskKey, hVolumeKey);
if (bModified) { // we have modified the registry
dwValue = (EndFlag == 0) ? SERVICE_DISABLED : SERVICE_BOOT_START; Status = RegSetValueEx( hDiskPerfKey, StartKey, 0L, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue)); //
// First update service registry entries
//
if (DisableRequest != 0) { nIrpStack = nIrpStackReg + nIncrement; if (EndFlag == 0) { //
// Turn off service completely
//
// Set Irp stack size to original value or default
if (nIrpStack < IRP_STACK_NODISKPERF) nIrpStack = IRP_STACK_NODISKPERF; } else { // else, there is only one stack left
if (nIrpStack < IRP_STACK_NODISKPERF+1) nIrpStack = IRP_STACK_NODISKPERF+1; } } else if (EnableRequest != 0) { nIrpStack = nIrpStackReg + nIncrement; //
// Set proper Irp stack size
//
if (EndFlag == (ENABLE_DISKDRIVE | ENABLE_VOLUME)) { if (nIrpStack < IRP_STACK_NODISKPERF+2) // a value is set
nIrpStack = IRP_STACK_NODISKPERF+2; } else { // at least one is enabled
if (nIrpStack < IRP_STACK_NODISKPERF+1) nIrpStack = IRP_STACK_NODISKPERF+1; } } } else { //
// No action taken. Should tell the user the state.
//
PrintStatus(TRUE, EndFlag, cMachineName); Dp_wprintf(GetFormatResource(DP_NOCHANGE)); }
#if DBG
fprintf(stderr, "New LargeIrp is %d\n", nIrpStack); #endif
if (hIOSystemKey != NULL && Status == ERROR_SUCCESS) { if (bModified) { Status = RegSetValueEx ( hIOSystemKey, LargeIrps, 0L, REG_DWORD, (LPBYTE)&nIrpStack, sizeof(DWORD)); if (Status == ERROR_SUCCESS) { PrintStatus(FALSE, EndFlag, cMachineName); } else { Dp_wprintf(GetFormatResource(DP_UNABLE_MODIFY_VALUE)); } } RegCloseKey(hIOSystemKey); }
DoChangeCommandCleanup: if (hDiskPerfKey != NULL) { RegCloseKey(hDiskPerfKey); } if (hDiskKey != NULL) { RegCloseKey(hDiskKey); } if (hVolumeKey != NULL) { RegCloseKey(hVolumeKey); } if (hRegistry != NULL) { RegCloseKey(hRegistry); } if (Status != ERROR_SUCCESS) { Dp_wprintf(GetFormatResource(DP_STATUS_FORMAT), Status); } return Status; }
ULONG OpenRegKeys( IN LPCTSTR lpszMachine, OUT PHKEY hRegistry, OUT PHKEY hDiskKey, OUT PHKEY hVolumeKey, OUT PHKEY hServiceKey ) { ULONG status;
if (hRegistry == NULL) return ERROR_INVALID_PARAMETER;
*hRegistry = NULL; status = RegConnectRegistry( lpszMachine, HKEY_LOCAL_MACHINE, hRegistry); if (status != ERROR_SUCCESS) return status; if (*hRegistry == NULL) return ERROR_INVALID_PARAMETER; // Avoid PREFIX error
if (hDiskKey) { *hDiskKey = NULL; if (status == ERROR_SUCCESS) { status = RegOpenKeyEx( *hRegistry, lpwszDiskDriveKey, (DWORD) 0, KEY_SET_VALUE | KEY_QUERY_VALUE, hDiskKey); } } if (hVolumeKey) { *hVolumeKey = NULL; if (status == ERROR_SUCCESS) { status = RegOpenKeyEx( *hRegistry, lpwszVolumeKey, (DWORD) 0, KEY_SET_VALUE | KEY_QUERY_VALUE, hVolumeKey); } } if (hServiceKey) { *hServiceKey = NULL; if (status == ERROR_SUCCESS) { status = RegOpenKeyEx( *hRegistry, lpwszDiskPerfKey, (DWORD) 0, KEY_SET_VALUE | KEY_QUERY_VALUE, hServiceKey); } } if ( (status != ERROR_SUCCESS) && (hDiskKey != NULL) ) { if (*hDiskKey != NULL) RegCloseKey(*hDiskKey); *hDiskKey = NULL; } if ( (status != ERROR_SUCCESS) && (hVolumeKey != NULL) ) { if (*hVolumeKey != NULL) RegCloseKey(*hVolumeKey); *hVolumeKey = NULL; } if ( (status != ERROR_SUCCESS) && (hServiceKey != NULL) ) { if (*hServiceKey != NULL) RegCloseKey(*hServiceKey); *hServiceKey = NULL; } return status; }
ULONG SetFilter( IN HKEY hKey, IN LPTSTR strFilterString, IN DWORD dwSize ) { ULONG status; LONG len; DWORD dwType = REG_MULTI_SZ;
if (hKey == NULL) return ERROR_BADKEY;
//
// NOTE: Assumes that strFilterString is always MAX_PATH, NULL padded
//
len = dwSize / sizeof(TCHAR); if (len < 2) { dwSize = 2 * sizeof(TCHAR); #if DBG
fprintf(stderr, "SetFilter: Length %d dwSize %d\n", len, dwSize); #endif
} else { // ensures 2 null character always
if (strFilterString[len-1] != 0) { // no trailing null
len += 2; strFilterString[len] = 0; strFilterString[len+1] = 0; #if DBG
fprintf(stderr, "SetFilter: New length(+2) %d\n", len); #endif
} else if (strFilterString[len-2] != 0) { // only one trailing null
len += 1; strFilterString[len+1] = 0; #if DBG
fprintf(stderr, "SetFilter: New length(+1) %d\n", len); #endif
} dwSize = len * sizeof(TCHAR); } if (len <= 2) { status = RegDeleteValue(hKey, REGSTR_VAL_UPPERFILTERS); #if DBG
fprintf(stderr, "Delete status = %d\n", status); #endif
return status; } status = RegSetValueEx( hKey, REGSTR_VAL_UPPERFILTERS, (DWORD) 0, dwType, (BYTE*)strFilterString, dwSize);
#if DBG
if (status != ERROR_SUCCESS) { _ftprintf(stderr, _T("SetFilter: Cannot query key %s status=%d\n"), REGSTR_VAL_UPPERFILTERS, status); } else { fprintf(stderr, "SetFilter: "); DbgPrintMultiSz(strFilterString, dwSize); fprintf(stderr, "\n"); } #endif
return status; }
ULONG GetFilter( IN HKEY hKey, OUT LPTSTR strFilterString, IN DWORD dwSize ) // Returns size of strFilterString
{ ULONG status;
if (hKey == NULL) return ERROR_BADKEY;
status = RegQueryValueEx( hKey, REGSTR_VAL_UPPERFILTERS, NULL, NULL, (BYTE*)strFilterString, &dwSize); if (status != ERROR_SUCCESS) { #if DBG
_ftprintf(stderr, _T("GetFilter: Cannot query key %s status=%d\n"), REGSTR_VAL_UPPERFILTERS, status); #endif
return 0; } #if DBG
else { fprintf(stderr, "GetFilter: "); DbgPrintMultiSz(strFilterString, dwSize); fprintf(stderr, "\n"); } #endif
return dwSize; }
ULONG CheckFilter(TCHAR *Buffer) { TCHAR *string = Buffer; ULONG stringLength, diskperfLen, result;
if (string == NULL) return 0; stringLength = _tcslen(string);
diskperfLen = _tcslen(DISKPERF_SERVICE_NAME);
result = FALSE; while(stringLength != 0) {
if ((diskperfLen == stringLength) && (_tcsicmp(string, DISKPERF_SERVICE_NAME) == 0)) { #if DBG
fprintf(stderr, "CheckFilter: string found at offset %d\n", (string - Buffer)); #endif
result = TRUE; break; } else { string += stringLength + 1; stringLength = _tcslen(string); } } return result; }
ULONG GetEnableFlag( IN HKEY hDiskKey, IN HKEY hVolumeKey ) // Returns the flags indicating what is enabled
{ ULONG bFlag = 0; TCHAR strFilter[MAX_PATH+1] = {0}; DWORD dwSize; ULONG status;
dwSize = sizeof(TCHAR) * (MAX_PATH+1); if (GetFilter(hDiskKey, strFilter, dwSize) > 0) { if (CheckFilter(strFilter)) bFlag |= ENABLE_DISKDRIVE; } #if DBG
else fprintf(stderr, "GetEnableFlag: No filters for disk drive\n"); #endif
dwSize = sizeof(TCHAR) * (MAX_PATH+1); if (GetFilter(hVolumeKey, strFilter, dwSize) > 0) { if (CheckFilter(strFilter)) bFlag |= ENABLE_VOLUME; } #if DBG
else fprintf(stderr, "GetEnableFlag: No filters for volume\n"); #endif
return bFlag; }
ULONG AddToFilter( IN HKEY hKey ) { TCHAR *string, buffer[MAX_PATH+1]; ULONG dataLength; DWORD dwType, dwSize;
dwSize = sizeof(TCHAR) * MAX_PATH; RtlZeroMemory(buffer, dwSize + sizeof(TCHAR)); string = buffer;
dataLength = GetFilter(hKey, buffer, dwSize); dwSize = dataLength; #if DBG
if (dataLength > 0) { fprintf(stderr, "AddToFilter: Original string "); DbgPrintMultiSz(buffer, dataLength); fprintf(stderr, "\n"); } else fprintf(stderr, "AddToFilter: Cannot get original string\n"); #endif
dataLength /= sizeof(TCHAR); if (dataLength != 0) { dataLength -= 1; } _tcscpy(&(string[dataLength]), DISKPERF_SERVICE_NAME); dwSize += (_tcslen(DISKPERF_SERVICE_NAME)+1) * sizeof(TCHAR);
#if DBG
fprintf(stderr, "AddToFilter: New string "); DbgPrintMultiSz(buffer, dataLength + _tcslen(DISKPERF_SERVICE_NAME)+1); fprintf(stderr, "\n"); #endif
return SetFilter(hKey, buffer, dwSize); }
void PrintStatus( IN BOOL bCurrent, IN ULONG EnableFlag, IN LPCTSTR cMachineName ) { DWORD dwValue; TCHAR OemDisplayStringBuffer[DISP_BUFF_LEN * 2];
dwValue = (EnableFlag == 0) ? SERVICE_DISABLED : SERVICE_BOOT_START; if ((EnableFlag & ENABLE_PERMANENT) | (EnableFlag & ENABLE_PERMANENT_IOCTL)) { _stprintf(OemDisplayStringBuffer, GetFormatResource(DP_PERMANENT_FORMAT), cMachineName); if (EnableFlag & ENABLE_PERMANENT_IOCTL) { Dp_wprintf(OemDisplayStringBuffer); _stprintf(OemDisplayStringBuffer, GetFormatResource(DP_PERMANENT_IOCTL), cMachineName); } else { Dp_wprintf(OemDisplayStringBuffer); _stprintf(OemDisplayStringBuffer, GetFormatResource(DP_PERMANENT_FORMAT1), cMachineName); Dp_wprintf(OemDisplayStringBuffer); _stprintf(OemDisplayStringBuffer, GetFormatResource(DP_PERMANENT_FORMAT2), cMachineName); } } else if ( (EnableFlag == (ENABLE_DISKDRIVE | ENABLE_VOLUME)) || (EnableFlag == 0) ) { _stprintf(OemDisplayStringBuffer, bCurrent ? GetFormatResource (DP_CURRENT_FORMAT1) : GetFormatResource (DP_NEW_DISKPERF_STATUS1), cMachineName, GetStringResource(REG_TO_DP_INDEX(dwValue))); } else { _stprintf (OemDisplayStringBuffer, bCurrent ? GetFormatResource (DP_CURRENT_FORMAT) : GetFormatResource (DP_NEW_DISKPERF_STATUS), (EnableFlag == ENABLE_DISKDRIVE) ? GetStringResource(DP_PHYSICAL) : GetStringResource(DP_LOGICAL), cMachineName, GetStringResource(REG_TO_DP_INDEX(dwValue))); } Dp_wprintf(OemDisplayStringBuffer); }
ULONG RemoveFromFilter( IN HKEY hKey ) { TCHAR *string, buffer[MAX_PATH+1]; ULONG dataLength, stringLength, diskperfLen, found; ULONG removeSize;
dataLength = sizeof(TCHAR) * (MAX_PATH+1); RtlZeroMemory(buffer, sizeof(TCHAR) * MAX_PATH); dataLength = GetFilter(hKey, buffer, dataLength); if (dataLength == 0) return 0;
#if DBG
fprintf(stderr, "RemoveFromFilter: Original string "); DbgPrintMultiSz(buffer, dataLength); fprintf(stderr, "'\n"); #endif
string = (TCHAR *) buffer; if(dataLength != 0) { dataLength -= sizeof(TCHAR); }
//
// now, find DiskPerf from the entry to remove it
//
stringLength = _tcslen(string);
diskperfLen = _tcslen(DISKPERF_SERVICE_NAME); // includes NULL
removeSize = (diskperfLen+1) * sizeof(TCHAR);
#if DBG
fprintf(stderr, "RemoveFromFilter: diskperfLen=%d removeSize=%d\n", diskperfLen, removeSize); #endif
found = FALSE; while(stringLength != 0 && !found) {
#if DBG
fprintf(stderr, "RemoveFromFilter: Loop stringLength=%d\n", stringLength); #endif
if (diskperfLen == stringLength) { if(_tcsicmp(string, DISKPERF_SERVICE_NAME) == 0) { //
// found it, so we will remove it right now
//
if (dataLength > removeSize) { RtlCopyMemory( string, string+stringLength+1, dataLength - removeSize); RtlZeroMemory( buffer + dataLength - removeSize, removeSize); } else { RtlZeroMemory( buffer, removeSize); } found = TRUE; } } else { // else, try the next entry
string += stringLength + 1; stringLength = _tcslen(string); } } dataLength = dataLength + sizeof(TCHAR) - removeSize; buffer[dataLength] = 0; /* if (dataLength == sizeof(TCHAR)) {
dataLength += sizeof(TCHAR); buffer[dataLength] = 0; } */
#if DBG
fprintf(stderr, "RemoveFromFilter: New string "); DbgPrintMultiSz(buffer, dataLength); fprintf(stderr, "\n"); #endif
return SetFilter(hKey, buffer, dataLength); }
/***
* Dp_wprintf(format) - print formatted data * * Prints Unicode formatted string to console window using WriteConsoleW. * Note: This Dp_wprintf() is used to workaround the problem in c-runtime * which looks up LC_CTYPE even for Unicode string. * */
int __cdecl Dp_wprintf( const wchar_t *format, ... )
{ DWORD cchWChar;
va_list args; va_start( args, format );
cchWChar = Dp_vfwprintf(stdout, format, args);
va_end(args);
return cchWChar; }
/***
* Dp_fwprintf(stream, format) - print formatted data * * Prints Unicode formatted string to console window using WriteConsoleW. * Note: This Dp_fwprintf() is used to workaround the problem in c-runtime * which looks up LC_CTYPE even for Unicode string. * */
int __cdecl Dp_fwprintf( FILE *str, const wchar_t *format, ... )
{ DWORD cchWChar;
va_list args; va_start( args, format );
cchWChar = Dp_vfwprintf(str, format, args);
va_end(args);
return cchWChar; }
int __cdecl Dp_vfwprintf( FILE *str, const wchar_t *format, va_list argptr )
{ HANDLE hOut;
if (str == stderr) { hOut = GetStdHandle(STD_ERROR_HANDLE); } else { hOut = GetStdHandle(STD_OUTPUT_HANDLE); }
if ((GetFileType(hOut) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR) { DWORD cchWChar; WCHAR szBufferMessage[1024];
vswprintf( szBufferMessage, format, argptr ); cchWChar = wcslen(szBufferMessage); WriteConsoleW(hOut, szBufferMessage, cchWChar, &cchWChar, NULL); return cchWChar; }
return vfwprintf(str, format, argptr); }
#if DBG
void DbgPrintMultiSz( TCHAR *String, ULONG Size ) { ULONG len;
#if DBG
fprintf(stderr, "%d ", Size); #endif
len = _tcslen(String); while (len > 0) { _ftprintf(stderr, _T("'%s' "), String); String += len+1; len = _tcslen(String); } } #endif
void SplitCommandLine( LPTSTR CommandLine, LPTSTR* pArgv ) {
LPTSTR arg; int i = 0; arg = _tcstok( CommandLine, _T(" \t")); while( arg != NULL ){ _tcscpy(pArgv[i++], arg); arg = _tcstok(NULL, _T(" \t")); } }
int __cdecl main( int argc, char **argv ) { LPTSTR *targv,*commandLine; ULONG Status = ERROR_SUCCESS; int i;
setlocale(LC_ALL, ".OCP");
MySetThreadUILanguage(0);
commandLine = (LPTSTR*)malloc( argc * sizeof(LPTSTR) ); if (!commandLine) exit(1); for(i=0;i<argc;i++){ commandLine[i] = (LPTSTR)malloc( (strlen(argv[i])+1) * sizeof(LPTSTR)); if (!commandLine[i]) exit(1); }
SplitCommandLine( GetCommandLine(), commandLine ); targv = commandLine;
hMod = (HINSTANCE)GetModuleHandle(NULL); // get instance ID of this module;
// check for command arguments
if (argc == CMD_SHOW_LOCAL_STATUS) { Status = DisplayStatus(NULL); // if (Status == ERROR_SUCCESS) {
// DisplayChangeCmd();
// }
} else if (argc >= CMD_DO_COMMAND) { if (ArgIsSystem(targv[1])) { Status = DisplayStatus (targv[1]); // if (Status != ERROR_SUCCESS) {
// DisplayChangeCmd();
// }
} else { // do change command
if (argc == LOCAL_CHANGE) { DoChangeCommand (targv[1], NULL); } else if (argc == REMOTE_CHANGE) { DoChangeCommand(targv[1], targv[2]); } else { DisplayChangeCmd(); } } } else { DisplayCmdHelp(); } Dp_wprintf(_T("\n"));
for(i=0;i<argc;i++){ free(commandLine[i]); commandLine[i] = NULL; } free(commandLine);
return 0; }
BOOL IsBeyondW2K( IN LPCTSTR lpszMachine, OUT PDWORD EnableCounter ) { OSVERSIONINFO OsVersion; HKEY hRegistry, hKey; TCHAR szBuildNumber[32]; TCHAR szVersion[32]; DWORD dwBuildNumber, dwMajor, status, dwSize; BOOL bRet = FALSE;
*EnableCounter = 0; if (lpszMachine != NULL) { if (*lpszMachine != 0) { status = RegConnectRegistry( lpszMachine, HKEY_LOCAL_MACHINE, &hRegistry); if (status != ERROR_SUCCESS) return FALSE; status = RegOpenKeyEx( hRegistry, lpwszOsVersionKey, (DWORD) 0, KEY_QUERY_VALUE, &hKey); if (status != ERROR_SUCCESS) { RegCloseKey(hRegistry); return FALSE; } dwSize = sizeof(TCHAR) * 32; status = RegQueryValueEx( hKey, lpwszBuildNumber, NULL, NULL, (BYTE*)szBuildNumber, &dwSize); if (status != ERROR_SUCCESS) { RegCloseKey(hKey); RegCloseKey(hRegistry); return FALSE; } status = RegQueryValueEx( hKey, lpwszOsVersion, NULL, NULL, (BYTE*)szVersion, &dwSize); if (status != ERROR_SUCCESS) { RegCloseKey(hKey); RegCloseKey(hRegistry); return FALSE; } RegCloseKey(hKey); status = RegOpenKeyEx( hRegistry, lpwszPartmgrKey, (DWORD) 0, KEY_QUERY_VALUE, &hKey); if (status == ERROR_SUCCESS) { *EnableCounter = 0; status = RegQueryValueEx( hKey, lpwszEnableCounterValue, NULL, NULL, (BYTE*) EnableCounter, &dwSize); if ((status != ERROR_SUCCESS) || (dwSize != sizeof(DWORD))) { *EnableCounter = 0; } } dwBuildNumber = _ttoi(szBuildNumber); dwMajor = _ttoi(szVersion); if ((dwMajor >= 5) && (dwBuildNumber > 2195)) { bRet = TRUE; status = RegOpenKeyEx( hRegistry, lpwszPartmgrKey, (DWORD) 0, KEY_QUERY_VALUE, &hKey); if (status == ERROR_SUCCESS) { status = RegQueryValueEx( hKey, lpwszEnableCounterValue, NULL, NULL, (BYTE*) EnableCounter, &dwSize); if ((status != ERROR_SUCCESS) || (dwSize != sizeof(DWORD))) { *EnableCounter = 0; } RegCloseKey(hKey); } } RegCloseKey(hRegistry); } } OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (GetVersionEx(&OsVersion)) { if ((OsVersion.dwMajorVersion >= 5) && (OsVersion.dwMinorVersion > 0) && (OsVersion.dwBuildNumber > 2195)) return TRUE; } return FALSE; }
ULONG EnableForIoctl( IN LPWSTR lpszMachineName ) { DWORD status; HKEY hRegistry, hKey; DWORD dwValue = 1;
hRegistry = NULL;
status = RegConnectRegistry( lpszMachineName, HKEY_LOCAL_MACHINE, &hRegistry); if (status != ERROR_SUCCESS) return status; if (hRegistry == NULL) return ERROR_INVALID_PARAMETER;
hKey = NULL; status = RegOpenKeyEx( hRegistry, lpwszPartmgrKey, (DWORD) 0, KEY_SET_VALUE | KEY_QUERY_VALUE, &hKey); if (status != ERROR_SUCCESS) { RegCloseKey(hRegistry); return status; } status = RegSetValueEx( hKey, lpwszEnableCounterValue, 0L, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue)); RegCloseKey(hKey); RegCloseKey(hRegistry); return 0; }
ULONG DisableForIoctl( IN LPWSTR lpszMachineName, IN ULONG Request ) { ULONG nDisk, i; SYSTEM_DEVICE_INFORMATION DeviceInfo; NTSTATUS status;
UNICODE_STRING UnicodeName; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus;
WCHAR devname[256]; PWCHAR s;
HANDLE PartitionHandle, MountMgrHandle, VolumeHandle; DWORD ReturnedBytes;
DWORD MountError; HKEY hRegistry, hKey;
status = RegConnectRegistry( lpszMachineName, HKEY_LOCAL_MACHINE, &hRegistry); if (status != ERROR_SUCCESS) return status; if (hRegistry == NULL) return ERROR_INVALID_PARAMETER;
status = RegOpenKeyEx( hRegistry, lpwszPartmgrKey, (DWORD) 0, KEY_SET_VALUE | KEY_QUERY_VALUE, &hKey); if (status != ERROR_SUCCESS) { RegCloseKey(hRegistry); return status; } RegDeleteValue(hKey, lpwszEnableCounterValue); RegCloseKey(hKey); RegCloseKey(hRegistry);
if (!(Request & ENABLE_DISKDRIVE)) goto DisableVolume; status = NtQuerySystemInformation(SystemDeviceInformation, &DeviceInfo, sizeof(DeviceInfo), NULL); if (!NT_SUCCESS(status)) { return 0; }
nDisk = DeviceInfo.NumberOfDisks; // for each physical disk
for (i = 0; i < nDisk; i++) {
swprintf(devname, L"\\Device\\Harddisk%d\\Partition0", i);
RtlInitUnicodeString(&UnicodeName, devname);
InitializeObjectAttributes( &ObjectAttributes, &UnicodeName, OBJ_CASE_INSENSITIVE, NULL, NULL ); // opening a partition handle for physical drives
status = NtOpenFile( &PartitionHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE );
if ( !NT_SUCCESS(status) ) { continue; } // sending IOCTL over to Partition Handle
if (!DeviceIoControl(PartitionHandle, IOCTL_DISK_PERFORMANCE_OFF, NULL, 0, NULL, 0, &ReturnedBytes, NULL )) { #if DBG
printf("IOCTL failed for %ws\n", devname); #endif
}
NtClose(PartitionHandle); }
DisableVolume: if (!(Request | ENABLE_VOLUME)) { return 0; }
MountMgrHandle = FindFirstVolumeW(devname, sizeof(devname)); if (MountMgrHandle == NULL) { #if DBG
printf("Cannot find first volume\n"); #endif
return 0; } s = (PWCHAR) &devname[wcslen(devname)-1]; if (*s == L'\\') { *s = UNICODE_NULL; }
VolumeHandle = CreateFile(devname, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE); if (VolumeHandle != INVALID_HANDLE_VALUE) { #if DBG
printf("Opened with success\n"); #endif
// sending IOCTL over to a volume handle
if (!DeviceIoControl(VolumeHandle, IOCTL_DISK_PERFORMANCE_OFF, NULL, 0, NULL, 0, &ReturnedBytes, NULL )) { #if DBG
printf("IOCTL failed for %ws\n", devname); #endif
} CloseHandle(VolumeHandle); }
while (FindNextVolumeW(MountMgrHandle, devname, sizeof(devname))) { s = (PWCHAR) &devname[wcslen(devname)-1]; if (*s == L'\\') { *s = UNICODE_NULL; } VolumeHandle = CreateFile(devname, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE); if (VolumeHandle != INVALID_HANDLE_VALUE) { #if DBG
printf("Opened with success\n"); #endif
if (!DeviceIoControl(VolumeHandle, IOCTL_DISK_PERFORMANCE_OFF, NULL, 0, NULL, 0, &ReturnedBytes, NULL )) { #if DBG
printf("IOCTL failed for %ws\n", devname); #endif
} CloseHandle(VolumeHandle); } } FindVolumeClose(MountMgrHandle); return 0; }
////////////////////////////////////////////////////////////////////////////
//
// MySetThreadUILanguage
//
// This routine sets the thread UI language based on the console codepage.
//
// 9-29-00 WeiWu Created.
// Copied from Base\Win32\Winnls so that it works in W2K as well
////////////////////////////////////////////////////////////////////////////
LANGID WINAPI MySetThreadUILanguage( WORD wReserved) { //
// Cache system locale and CP info
//
static LCID s_lidSystem = 0; static UINT s_uiSysCp = 0; static UINT s_uiSysOEMCp = 0;
ULONG uiUserUICp; ULONG uiUserUIOEMCp; WCHAR szData[16]; UNICODE_STRING ucStr;
LANGID lidUserUI = GetUserDefaultUILanguage(); LCID lcidThreadOld = GetThreadLocale();
//
// Set default thread locale to EN-US
//
// This allow us to fall back to English UI to avoid trashed characters
// when console doesn't meet the criteria of rendering native UI.
//
LCID lcidThread = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); UINT uiConsoleCp = GetConsoleOutputCP();
//
// Make sure nobody uses it yet
//
ASSERT(wReserved == 0);
//
// Get cached system locale and CP info.
//
if (!s_uiSysCp) { LCID lcidSystem = GetSystemDefaultLCID();
if (lcidSystem) { //
// Get ANSI CP
//
GetLocaleInfoW(lcidSystem, LOCALE_IDEFAULTANSICODEPAGE, szData, sizeof(szData)/sizeof(WCHAR)); RtlInitUnicodeString(&ucStr, szData); RtlUnicodeStringToInteger(&ucStr, 10, &uiUserUICp);
//
// Get OEM CP
//
GetLocaleInfoW(lcidSystem, LOCALE_IDEFAULTCODEPAGE, szData, sizeof(szData)/sizeof(WCHAR)); RtlInitUnicodeString(&ucStr, szData); RtlUnicodeStringToInteger(&ucStr, 10, &s_uiSysOEMCp); //
// Cache system primary langauge
//
s_lidSystem = PRIMARYLANGID(LANGIDFROMLCID(lcidSystem)); } }
//
// Don't cache user UI language and CP info, UI language can be changed without system reboot.
//
if (lidUserUI) { GetLocaleInfoW(MAKELCID(lidUserUI,SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szData, sizeof(szData)/sizeof(WCHAR)); RtlInitUnicodeString(&ucStr, szData); RtlUnicodeStringToInteger(&ucStr, 10, &uiUserUICp);
GetLocaleInfoW(MAKELCID(lidUserUI,SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, szData, sizeof(szData)/sizeof(WCHAR)); RtlInitUnicodeString(&ucStr, szData); RtlUnicodeStringToInteger(&ucStr, 10, &uiUserUIOEMCp); }
//
// Complex scripts cannot be rendered in the console, so we
// force the English (US) resource.
//
if (uiConsoleCp && s_lidSystem != LANG_ARABIC && s_lidSystem != LANG_HEBREW && s_lidSystem != LANG_VIETNAMESE && s_lidSystem != LANG_THAI) { //
// Use UI language for console only when console CP, system CP and UI language CP match.
//
if ((uiConsoleCp == s_uiSysCp || uiConsoleCp == s_uiSysOEMCp) && (uiConsoleCp == uiUserUICp || uiConsoleCp == uiUserUIOEMCp)) { lcidThread = MAKELCID(lidUserUI, SORT_DEFAULT); } }
//
// Set the thread locale if it's different from the currently set
// thread locale.
//
if ((lcidThread != lcidThreadOld) && (!SetThreadLocale(lcidThread))) { lcidThread = lcidThreadOld; }
//
// Return the thread locale that was set.
//
return (LANGIDFROMLCID(lcidThread)); }
|