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.
 
 
 
 
 
 

857 lines
30 KiB

#include "pch.h"
#pragma hdrstop
#include <tchar.h> // _tprintf
#include <initguid.h>
#include "uuid.h"
#include <ccstock.h>
#include "util.h"
#include "config.h"
#include "security.h"
const TCHAR g_szKeyPolicy[] = TEXT("Software\\Policies\\Microsoft\\Windows\\NetCache");
const TCHAR g_szKeyPrefs[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\NetCache");
const TCHAR g_szKeyCustomActions[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\NetCache\\CustomGoOfflineActions");
const TCHAR g_szValEnabled[] = TEXT("Enabled");
const TCHAR g_szValEncrypted[] = TEXT("Encrypted");
const TCHAR g_szValGoOfflineAction[] = TEXT("GoOfflineAction");
const TCHAR g_szValDefCacheSize[] = TEXT("DefCacheSize");
const TCHAR g_szValNoConfigCache[] = TEXT("NoConfigCache");
const TCHAR g_szValNoCacheViewer[] = TEXT("NoCacheViewer");
const TCHAR g_szValNoMakeAvailableOffline[] = TEXT("NoMakeAvailableOffline");
const TCHAR g_szValNoReminders[] = TEXT("NoReminders");
const TCHAR g_szValNoConfigReminders[] = TEXT("NoConfigReminders");
const TCHAR g_szValSyncAtLogoff[] = TEXT("SyncAtLogoff");
const TCHAR g_szValReminderFreqMinutes[] = TEXT("ReminderFreqMinutes");
const TCHAR g_szValInitialBalloonTimeout[] = TEXT("InitialBalloonTimeoutSeconds");
const TCHAR g_szValReminderBalloonTimeout[] = TEXT("ReminderBalloonTimeoutSeconds");
const TCHAR g_szValFirstPinWizardShown[] = TEXT("FirstPinWizardShown");
const TCHAR g_szValExpandStatusDlg[] = TEXT("ExpandStatusDlg");
const TCHAR g_szValFormatCscDb[] = TEXT("FormatDatabase");
const TCHAR g_szValEventLoggingLevel[] = TEXT("EventLoggingLevel");
const TCHAR g_szValPurgeAtLogoff[] = TEXT("PurgeAtLogoff");
const TCHAR g_szValExtExclusionList[] = TEXT("ExtExclusionList");
const TCHAR g_szValAlwaysPinSubFolders[] = TEXT("AlwaysPinSubFolders");
const TCHAR g_szNA[] = TEXT("<n/a>");
const DWORD POL_CU = 0x0001; // Current user
const DWORD POL_LM = 0x0002; // Local machine
const DWORD PREF_CU = 0x0004;
const DWORD PREF_LM = 0x0008;
const DWORD PREF_BOTH = PREF_CU | PREF_LM;
const DWORD POL_BOTH = POL_CU | POL_LM;
const DWORD REG_ALL = PREF_BOTH | POL_BOTH;
const DWORD PREF = 1;
const DWORD POLICY = 2;
LPTSTR GoOfflineActionText(
int iValue,
LPTSTR pszDest
)
{
LPCTSTR rgpsz[] = { TEXT("(Work offline)"),
TEXT("(No offline)") };
if (iValue >= 0 && iValue < ARRAYSIZE(rgpsz))
lstrcpy(pszDest, rgpsz[iValue]);
else
lstrcpy(pszDest, TEXT("<unknown>"));
return pszDest;
}
LPTSTR SyncAtLogoffText(
int iValue,
LPTSTR pszDest
)
{
LPCTSTR rgpsz[] = { TEXT("(Part sync)"),
TEXT("(Full sync)") };
if (iValue >= 0 && iValue < ARRAYSIZE(rgpsz))
lstrcpy(pszDest, rgpsz[iValue]);
else
lstrcpy(pszDest, TEXT("<unknown>"));
return pszDest;
}
LPTSTR DefCacheSizeText(
int iValue,
LPTSTR pszDest
)
{
wsprintf(pszDest, TEXT("(%2d.%02d %%)"), iValue / 100, iValue % 100);
return pszDest;
}
LPCTSTR BoolText(bool b)
{
static const LPCTSTR rgYN[] = { TEXT("No"), TEXT("Yes") };
return rgYN[int(b)];
}
LPCTSTR
RegValStr(
HKEY hkeyRoot,
LPCTSTR pszSubkey,
LPCTSTR pszValue,
LPTSTR pszDest
)
{
DWORD dwValue = 0;
DWORD cbData = sizeof(dwValue);
DWORD dwType;
DWORD dwError = SHGetValue(hkeyRoot,
pszSubkey,
pszValue,
&dwType,
(LPVOID)&dwValue,
&cbData);
if (ERROR_SUCCESS == dwError)
{
wsprintf(pszDest, TEXT("%d"), dwValue);
}
else if (ERROR_FILE_NOT_FOUND == dwError)
{
lstrcpy(pszDest, TEXT("<none>"));
}
else
{
wsprintf(pszDest, TEXT("Err %d"), dwError);
}
return pszDest;
}
LPTSTR GetOsVersionInfoText(
LPTSTR pszDest
)
{
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
*pszDest = TEXT('\0');
if (GetVersionEx(&osvi))
{
static const TCHAR szUnknown[] = TEXT("Unknown OS");
static const struct
{
DWORD dwPlatform;
DWORD dwMinorVersion;
LPCTSTR pszPlatform;
} rgPlatforms[] = {{ VER_PLATFORM_WIN32s, (DWORD)-1, TEXT("Win32s") },
{ VER_PLATFORM_WIN32_WINDOWS, 0, TEXT("Windows 95") },
{ VER_PLATFORM_WIN32_WINDOWS, 10, TEXT("Windows 98") },
{ VER_PLATFORM_WIN32_NT, (DWORD)-1, TEXT("Windows NT") }};
static const struct
{
DWORD dwOS;
LPCTSTR pszOS;
} rgOS[] = {{ OS_WIN2000TERMINAL, TEXT("Windows 2000 Terminal") },
{ OS_WIN2000PRO, TEXT("Windows 2000 Professional") },
{ OS_WIN2000ADVSERVER, TEXT("Windows 2000 Advanced Server") },
{ OS_WIN2000DATACENTER, TEXT("Windows 2000 Data Center") },
{ OS_WIN2000SERVER, TEXT("Windows 2000 Server") },
{ OS_WIN2000, TEXT("Windows 2000") },
{ OS_NT5, TEXT("Windows NT") },
{ OS_NT4, TEXT("Windows NT") },
{ OS_NT, TEXT("Windows NT") },
{ OS_MEMPHIS_GOLD, TEXT("Windows 98") },
{ OS_MEMPHIS, TEXT("Windows 98 (beta)") },
{ OS_WIN95, TEXT("Windows 95") },
{ OS_WINDOWS, TEXT("Windows") }};
LPCTSTR pszPlatform = szUnknown;
int i = 0;
//
// IsOS() is the shlwapi API for figuring out the OS type. Currently, it
// provides better granularity than GetVersionEx.
//
for (i = 0; i < ARRAYSIZE(rgOS); i++)
{
if (IsOS(rgOS[i].dwOS))
{
pszPlatform = rgOS[i].pszOS;
break;
}
}
//
// If IsOS() wasn't able to determine the platform, take the platform from
// the GetVersionEx results.
//
if (szUnknown == pszPlatform)
{
for (i = 0; i < ARRAYSIZE(rgPlatforms); i++)
{
if (rgPlatforms[i].dwPlatform == osvi.dwPlatformId)
{
if ((DWORD)-1 == rgPlatforms[i].dwMinorVersion ||
osvi.dwMinorVersion == rgPlatforms[i].dwMinorVersion)
{
pszPlatform = rgPlatforms[i].pszPlatform;
break;
}
}
}
}
wsprintf(pszDest, TEXT("%s version %d.%d %s build %d\n\n"), pszPlatform,
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.szCSDVersion,
osvi.dwBuildNumber);
}
return pszDest;
}
void DumpRegStats(void)
{
TCHAR szScratch[MAX_PATH];
CConfig &config = CConfig::GetSingleton();
typedef bool (CConfig::*PBMF)(bool *bSetByPolicy) const;
typedef int (CConfig::*PIMF)(bool *bSetByPolicy) const;
typedef LPTSTR (*PDF)(int iValue, LPTSTR pszDest);
struct
{
LPCTSTR pszTitle;
DWORD dwReg;
HKEY hkeyRoot;
LPCTSTR pszSubkey;
} rgRegKeys[] = {{ TEXT("Policy (LM)"), POL_LM, HKEY_LOCAL_MACHINE, g_szKeyPolicy },
{ TEXT("Policy (CU)"), POL_CU, HKEY_CURRENT_USER, g_szKeyPolicy },
{ TEXT("Pref (LM)"), PREF_LM, HKEY_LOCAL_MACHINE, g_szKeyPrefs },
{ TEXT("Pref (CU)"), PREF_CU, HKEY_CURRENT_USER, g_szKeyPrefs }};
struct
{
LPCTSTR pszValue;
DWORD dwReg;
PBMF pfnBool;
PIMF pfnInt;
PDF pfnDesc;
} rgRegValues[] = {
{ g_szValDefCacheSize, POL_LM, NULL, (PIMF)&CConfig::DefaultCacheSize, &DefCacheSizeText },
{ g_szValEnabled, POL_LM, &CConfig::CscEnabled, NULL, NULL },
{ g_szValNoConfigCache, POL_BOTH, &CConfig::NoConfigCache, NULL, NULL },
{ g_szValNoCacheViewer, POL_BOTH, &CConfig::NoCacheViewer, NULL, NULL },
{ g_szValNoMakeAvailableOffline, POL_BOTH, &CConfig::NoMakeAvailableOffline, NULL, NULL },
{ g_szValGoOfflineAction, PREF_CU | POL_BOTH, NULL, &CConfig::GoOfflineAction, &GoOfflineActionText },
{ g_szValEventLoggingLevel, REG_ALL, NULL, &CConfig::EventLoggingLevel, NULL },
{ g_szValFirstPinWizardShown, PREF_CU, (PBMF)&CConfig::FirstPinWizardShown, NULL, NULL },
{ g_szValNoReminders, POL_BOTH | PREF_CU, &CConfig::NoReminders, NULL, NULL },
{ g_szValPurgeAtLogoff, POL_LM, &CConfig::PurgeAtLogoff, NULL, NULL },
{ g_szValSyncAtLogoff, POL_BOTH | PREF_CU, NULL, &CConfig::SyncAtLogoff, &SyncAtLogoffText },
{ g_szValInitialBalloonTimeout, POL_BOTH, NULL, &CConfig::InitialBalloonTimeoutSeconds, NULL },
{ g_szValReminderBalloonTimeout, POL_BOTH, NULL, &CConfig::ReminderBalloonTimeoutSeconds, NULL },
{ g_szValReminderFreqMinutes, POL_BOTH | PREF_CU, NULL, &CConfig::ReminderFreqMinutes, NULL },
{ g_szValAlwaysPinSubFolders, POL_LM, &CConfig::AlwaysPinSubFolders, NULL, NULL }
};
_tprintf(TEXT("Registry Information:\n\n"));
_tprintf(TEXT("%-30s%15s%15s%15s%15s%15s\n"),
TEXT("Value"),
rgRegKeys[0].pszTitle,
rgRegKeys[1].pszTitle,
rgRegKeys[2].pszTitle,
rgRegKeys[3].pszTitle,
TEXT("Result"));
for (int iVal = 0; iVal < ARRAYSIZE(rgRegValues); iVal++)
{
PBMF pfnBool = rgRegValues[iVal].pfnBool;
PIMF pfnInt = rgRegValues[iVal].pfnInt;
_tprintf(TEXT("%-30s"), rgRegValues[iVal].pszValue);
for (int iKey = 0; iKey < ARRAYSIZE(rgRegKeys); iKey++)
{
if (rgRegValues[iVal].dwReg & rgRegKeys[iKey].dwReg)
{
_tprintf(TEXT("%15s"), RegValStr(rgRegKeys[iKey].hkeyRoot,
rgRegKeys[iKey].pszSubkey,
rgRegValues[iVal].pszValue,
szScratch));
}
else
{
_tprintf(TEXT("%15s"), g_szNA);
}
}
int iValue = 0;
if (NULL != pfnBool)
iValue = (config.*pfnBool)(NULL);
else
iValue = (config.*pfnInt)(NULL);
_tprintf(TEXT("%15d"), iValue);
if (NULL != rgRegValues[iVal].pfnDesc)
_tprintf(TEXT(" %s"), (*rgRegValues[iVal].pfnDesc)(iValue, szScratch));
_tprintf(TEXT("\n"));
}
_tprintf(TEXT("\n"));
CConfig::OfflineActionIter iter = config.CreateOfflineActionIter();
CConfig::OfflineActionInfo oai;
_tprintf(TEXT("Offline action exceptions. Default is %s:\n\n"), GoOfflineActionText(config.GoOfflineAction(), szScratch));
_tprintf(TEXT("%-30s%s\n"), TEXT("Server"), TEXT("Action"));
while(S_OK == iter.Next(&oai))
{
_tprintf(TEXT("%-30s%s\n"), oai.szServer, GoOfflineActionText(oai.iAction, szScratch));
}
}
LPTSTR GetMachineName(
LPTSTR pszDest,
UINT cchDest
)
{
ULONG cchComputer = cchDest;
GetComputerName(pszDest, &cchComputer);
return pszDest;
}
LPTSTR FormatDateTime(
const SYSTEMTIME& time,
LPTSTR pszDest,
UINT cchDest
)
{
LPTSTR pszWrite = pszDest;
GetDateFormat(LOCALE_USER_DEFAULT,
DATE_SHORTDATE,
&time,
NULL,
pszWrite,
cchDest);
lstrcat(pszWrite, TEXT(" "));
int len = lstrlen(pszWrite);
pszWrite += len;
cchDest -= len;
GetTimeFormat(LOCALE_USER_DEFAULT,
LOCALE_NOUSEROVERRIDE,
&time,
NULL,
pszWrite,
cchDest);
return pszDest;
}
LPTSTR GetCurrentDateTime(
LPTSTR pszDest,
UINT cchDest
)
{
SYSTEMTIME now;
GetLocalTime(&now);
return FormatDateTime(now, pszDest, cchDest);
}
LPTSTR
Int64ToCommaSepString(
LONGLONG n,
LPTSTR pszOut,
int cchOut
)
{
ULONG ulTemp;
UNICODE_STRING s;
NUMBERFMTW nfmtW;
LPWSTR pszFmtOutW;
int cchFmtOut;
WCHAR szTextW[30];
WCHAR szSep[5];
//
// Convert the 64-bit int to a text string.
//
s.Length = 0;
s.MaximumLength = ARRAYSIZE(szTextW);
s.Buffer = szTextW;
RtlInt64ToUnicodeString(n, 10, &s);
//
// Format the number with commas according to locale conventions.
//
nfmtW.NumDigits = 0;
nfmtW.LeadingZero = 0;
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szSep, ARRAYSIZE(szSep));
RtlInitUnicodeString(&s, szSep);
RtlUnicodeStringToInteger(&s, 10, &ulTemp);
nfmtW.Grouping = UINT(ulTemp);
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, ARRAYSIZE(szSep));
nfmtW.lpDecimalSep = nfmtW.lpThousandSep = szSep;
nfmtW.NegativeOrder = 0;
#ifndef UNICODE
//
// If ansi build we need a wide-char buffer as format destination.
//
WCHAR szNumW[30];
pszFmtOutW = szNumW;
cchFmtOut = ARRAYSIZE(szNumW);
#else
//
// If unicode build we can format directly to the destination buffer.
//
pszFmtOutW = pszOut;
cchFmtOut = cchOut;
#endif
GetNumberFormatW(LOCALE_USER_DEFAULT,
0,
szTextW,
&nfmtW,
pszFmtOutW,
cchFmtOut);
#ifndef UNICODE
//
// If ansi build, need extra step to convert formatted number string
// (wide char) back to ansi.
//
WideCharToMultiByte(CP_ACP,
0,
pszFmtOutW,
-1,
pszOut,
cchOut,
NULL,
NULL);
#endif
return pszOut;
}
void PrintFileStatusFlags(void)
{
struct
{
DWORD dwFlags;
LPCTSTR pszText;
} rgMap[] = {{ FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED, TEXT("Data locally modified") },
{ FLAG_CSC_COPY_STATUS_ATTRIB_LOCALLY_MODIFIED, TEXT("Attrib locally modified") },
{ FLAG_CSC_COPY_STATUS_TIME_LOCALLY_MODIFIED, TEXT("Time locally modified") },
{ FLAG_CSC_COPY_STATUS_STALE, TEXT("Stale") },
{ FLAG_CSC_COPY_STATUS_LOCALLY_DELETED, TEXT("Locally deleted") },
{ FLAG_CSC_COPY_STATUS_SPARSE, TEXT("Sparse") },
{ FLAG_CSC_COPY_STATUS_ORPHAN, TEXT("Orphan") },
{ FLAG_CSC_COPY_STATUS_SUSPECT, TEXT("Suspect") },
{ FLAG_CSC_COPY_STATUS_LOCALLY_CREATED, TEXT("Locally created") },
{ 0x00010000, TEXT("User has READ access") },
{ 0x00020000, TEXT("User has WRITE access") },
{ 0x00040000, TEXT("Guest has READ access") },
{ 0x00080000, TEXT("Guest has WRITE access") },
{ 0x00100000, TEXT("Other has READ access") },
{ 0x00200000, TEXT("Other has WRITE access") },
{ FLAG_CSC_COPY_STATUS_IS_FILE, TEXT("Entry is a file") },
{ FLAG_CSC_COPY_STATUS_FILE_IN_USE, TEXT("File in use") },
};
_tprintf(TEXT("\nFile status flags ------------------------\n\n"));
for (int i = 0; i < ARRAYSIZE(rgMap); i++)
{
_tprintf(TEXT("0x%08X %s\n"), rgMap[i].dwFlags, rgMap[i].pszText);
}
_tprintf(TEXT("\n\n"));
}
void PrintShareStatusFlags(void)
{
struct
{
DWORD dwFlags;
LPCTSTR pszText;
} rgMap[] = {{ FLAG_CSC_SHARE_STATUS_MANUAL_REINT, TEXT("Manual Caching") }, // 0x00000000
{ FLAG_CSC_SHARE_STATUS_MODIFIED_OFFLINE, TEXT("Modified offline") }, // 0x00000001
{ FLAG_CSC_SHARE_STATUS_AUTO_REINT, TEXT("Auto Caching") }, // 0x00000040
{ FLAG_CSC_SHARE_STATUS_VDO, TEXT("Virtually Disconnected Ops") }, // 0x00000080
{ FLAG_CSC_SHARE_STATUS_NO_CACHING, TEXT("No Caching") }, // 0x000000C0
{ FLAG_CSC_SHARE_STATUS_FINDS_IN_PROGRESS, TEXT("Finds in progress") }, // 0x00000200
{ FLAG_CSC_SHARE_STATUS_FILES_OPEN, TEXT("Open files") }, // 0x00000400
{ FLAG_CSC_SHARE_STATUS_CONNECTED, TEXT("Connected") }, // 0x00000800
{ FLAG_CSC_SHARE_MERGING, TEXT("Merging") }, // 0x40000000
{ FLAG_CSC_SHARE_STATUS_DISCONNECTED_OP, TEXT("Disconnected Op") }, // 0x80000000
};
_tprintf(TEXT("\nShare status flags -------------------\n\n"));
for (int i = 0; i < ARRAYSIZE(rgMap); i++)
{
_tprintf(TEXT("%30s0x%08X %s\n"), TEXT(""), rgMap[i].dwFlags, rgMap[i].pszText);
}
_tprintf(TEXT("\n\n"));
}
void PrintHintFlags(void)
{
struct
{
DWORD dwFlags;
LPCTSTR pszText;
} rgMap[] = {{ FLAG_CSC_HINT_PIN_USER, TEXT("Pin User") }, // 0x00000001
{ FLAG_CSC_HINT_PIN_INHERIT_USER, TEXT("Pin Inherit User") }, // 0x00000002
{ FLAG_CSC_HINT_PIN_INHERIT_SYSTEM, TEXT("Pin Inherit System") }, // 0x00000004
{ FLAG_CSC_HINT_CONSERVE_BANDWIDTH, TEXT("Conserve Bandwidth") }, // 0x00000008
{ FLAG_CSC_HINT_PIN_SYSTEM, TEXT("Pin System") }, // 0x00000010
};
_tprintf(TEXT("\nFile hint flags -------------------\n\n"));
for (int i = 0; i < ARRAYSIZE(rgMap); i++)
{
_tprintf(TEXT("0x%08X %s\n"), rgMap[i].dwFlags, rgMap[i].pszText);
}
_tprintf(TEXT("\n\n"));
}
void DumpCacheStats(void)
{
DWORD dwStatus;
WIN32_FIND_DATA fd;
TCHAR szScratch[MAX_PATH];
BOOL bEnabled = CSCIsCSCEnabled();
CSCSPACEUSAGEINFO sui;
ZeroMemory(&sui, sizeof(sui));
GetCscSpaceUsageInfo(&sui);
_tprintf(TEXT("Cache information:\n\n"));
_tprintf(TEXT("CSC enabled.........: %s\n"), BoolText(boolify(CSCIsCSCEnabled())));
_tprintf(TEXT("Volume..............: %s\n"), sui.szVolume);
_tprintf(TEXT("Bytes on volume.....: %s\n"), Int64ToCommaSepString(sui.llBytesOnVolume, szScratch, ARRAYSIZE(szScratch)));
_tprintf(TEXT("Bytes in cache......: %s\n"), Int64ToCommaSepString(sui.llBytesTotalInCache, szScratch, ARRAYSIZE(szScratch)));
_tprintf(TEXT("Bytes used in cache.: %s\n"), Int64ToCommaSepString(sui.llBytesUsedInCache, szScratch, ARRAYSIZE(szScratch)));
_tprintf(TEXT("Files in cache......: %d\n"), sui.dwNumFilesInCache);
_tprintf(TEXT("Directories in cache: %d\n\n"), sui.dwNumDirsInCache);
CCscFindHandle hFind(CacheFindFirst(NULL, &fd, &dwStatus, NULL, NULL, NULL));
if (hFind.IsValid())
{
BOOL bResult = TRUE;
CSCSHARESTATS ss;
CSCCACHESTATS cs;
CSCGETSTATSINFO si = { SSEF_NONE, SSUF_NONE, true, false };
ZeroMemory(&cs, sizeof(cs));
_tprintf(TEXT("%-30s%-12s%10s%10s%10s%10s%10s%10s%10s%10s%10s%12s\n"),
TEXT("Share"),
TEXT("Status"),
TEXT("Files"),
TEXT("Dirs"),
TEXT("Pinned"),
TEXT("Modified"),
TEXT("Sparse"),
TEXT("USER"),
TEXT("GUEST"),
TEXT("OTHER"),
TEXT("Offline?"),
TEXT("OpenFiles?"));
do
{
cs.cShares++;
if (bResult = _GetShareStatistics(fd.cFileName,
&si,
&ss))
{
_tprintf(TEXT("%-30s0x%08X %10d%10d%10d%10d%10d%10d%10d%10d%10s%12s\n"),
fd.cFileName,
dwStatus,
ss.cTotal - ss.cDirs,
ss.cDirs,
ss.cPinned,
ss.cModified,
ss.cSparse,
ss.cAccessUser,
ss.cAccessGuest,
ss.cAccessOther,
BoolText(ss.bOffline),
BoolText(ss.bOpenFiles));
cs.cTotal += ss.cTotal;
cs.cPinned += ss.cPinned;
cs.cModified += ss.cModified;
cs.cSparse += ss.cSparse;
cs.cDirs += ss.cDirs;
cs.cAccessUser += ss.cAccessUser;
cs.cAccessGuest += ss.cAccessGuest;
cs.cAccessOther += ss.cAccessOther;
cs.cSharesOffline += int(ss.bOffline);
cs.cSharesWithOpenFiles += int(ss.bOpenFiles);
}
}
while(bResult && CacheFindNext(hFind, &fd, &dwStatus, NULL, NULL, NULL));
_tprintf(TEXT("%-30s%-12s%10d%10d%10d%10d%10d%10d%10d%10d%10d%12d\n\n"),
TEXT("SUMMARY"),
TEXT(""),
cs.cTotal - cs.cDirs,
cs.cDirs,
cs.cPinned,
cs.cModified,
cs.cSparse,
cs.cAccessUser,
cs.cAccessGuest,
cs.cAccessOther,
cs.cSharesOffline,
cs.cSharesWithOpenFiles);
}
}
void DumpFileInformation(LPCTSTR pszFile)
{
TCHAR szExpanded[MAX_PATH*2];
ExpandEnvironmentStrings(pszFile, szExpanded, ARRAYSIZE(szExpanded));
HANDLE hFile = CreateFile(szExpanded,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
BY_HANDLE_FILE_INFORMATION fi;
if (GetFileInformationByHandle(hFile, &fi))
{
TCHAR szScratch[80];
ULARGE_INTEGER llSize = { fi.nFileSizeLow, fi.nFileSizeHigh };
FILETIME localfiletime;
SYSTEMTIME systime;
FileTimeToLocalFileTime(&fi.ftLastWriteTime, &localfiletime);
FileTimeToSystemTime(&localfiletime, &systime);
_tprintf(TEXT("File.......: %s\n"), szExpanded);
_tprintf(TEXT("Size.......: %s bytes\n"), Int64ToCommaSepString(llSize.QuadPart, szScratch, ARRAYSIZE(szScratch)));
_tprintf(TEXT("Created....: %s\n\n"), FormatDateTime(systime, szScratch, ARRAYSIZE(szScratch)));
}
CloseHandle(hFile);
}
else
{
_tprintf(TEXT("ERROR %d opening %s\n\n"), GetLastError(), szExpanded);
}
}
void PrintOneEnumEntry(LPCTSTR pszPath, DWORD dwStatus, DWORD dwPinCount, DWORD dwHintFlags)
{
_tprintf(TEXT("0x%08X %d 0x%08X %s\n"), dwStatus, dwPinCount, dwHintFlags, pszPath);
}
void EnumTree(LPTSTR pszPath, LPTSTR pszPathToPrint)
{
WIN32_FIND_DATA fd;
DWORD dwStatus, dwPinCount, dwHintFlags;
CCscFindHandle hFind(CacheFindFirst(pszPath, &fd, &dwStatus, &dwPinCount, &dwHintFlags, NULL));
if (hFind.IsValid())
{
do
{
if (!PathIsDotOrDotDot(pszPath))
{
const bool bIsDir = 0 != (FILE_ATTRIBUTE_DIRECTORY & fd.dwFileAttributes);
PathCombine(pszPathToPrint, pszPath, fd.cFileName);
if (bIsDir)
{
lstrcat(pszPathToPrint, TEXT(" [DIR]"));
}
PrintOneEnumEntry(pszPathToPrint, dwStatus, dwPinCount, dwHintFlags);
if (bIsDir)
{
PathAppend(pszPath, fd.cFileName);
EnumTree(pszPath, pszPathToPrint);
}
}
}
while(CacheFindNext(hFind, &fd, &dwStatus, &dwPinCount, &dwHintFlags, NULL));
}
PathRemoveFileSpec(pszPath);
}
void EnumFiles(void)
{
WIN32_FIND_DATA fd;
DWORD dwStatus, dwPinCount, dwHintFlags;
_tprintf(TEXT("Status PinCnt Hints Name\n"));
CCscFindHandle hFind(CacheFindFirst(NULL, &fd, &dwStatus, &dwPinCount, &dwHintFlags, NULL));
if (hFind.IsValid())
{
do
{
//
// We create only one path and print-path buffer that we pass
// into the recursive EnumTree() function. This way we don't have
// a path buffer on each call stack as we recurse.
//
TCHAR szPath[MAX_PATH * 2]; // Working path buffer.
TCHAR szPathToPrint[MAX_PATH * 2]; // For printing only.
wsprintf(szPathToPrint, TEXT("%s [SHARE]"), fd.cFileName);
PrintOneEnumEntry(szPathToPrint, dwStatus, dwPinCount, dwHintFlags);
lstrcpyn(szPath, fd.cFileName, ARRAYSIZE(szPath));
EnumTree(szPath, szPathToPrint);
}
while(CacheFindNext(hFind, &fd, &dwStatus, &dwPinCount, &dwHintFlags, NULL));
}
_tprintf(TEXT("\n\n"));
}
void ShowUsage(void)
{
_tprintf(TEXT("\aUsage: cscsniff [-f] [-c] [-r] [-e] [-a]\n\n"));
_tprintf(TEXT("\t-f = Show file information.\n"));
_tprintf(TEXT("\t-c = Show cache information.\n"));
_tprintf(TEXT("\t-r = Show registry information.\n"));
_tprintf(TEXT("\t-e = Enumerate all files.\n"));
_tprintf(TEXT("\t-a = Show ALL output.\n\n"));
_tprintf(TEXT("Default is -f -c -r\n"));
}
void __cdecl main(int argc, char **argv)
{
// if (!IsCurrentUserAnAdminMember())
// {
// _tprintf(TEXT("\aYou must be an administrator on this computer to run cscsniff.\n"));
// return;
// }
const char chDash = '-';
const char chSlash = '/';
const DWORD SHOW_CACHEINFO = 0x00000001;
const DWORD SHOW_REGINFO = 0x00000002;
const DWORD SHOW_FILEINFO = 0x00000004;
const DWORD SHOW_ENUMFILES = 0x00000008;
const DWORD SHOW_DEFAULT = SHOW_CACHEINFO | SHOW_REGINFO | SHOW_FILEINFO;
const DWORD SHOW_ALL = SHOW_DEFAULT | SHOW_ENUMFILES;
DWORD dwShow = 0;
for (int i = 1; i < argc; i++)
{
if (chDash == argv[i][0] || chSlash == argv[i][0])
{
switch(argv[i][1])
{
case 'C':
case 'c':
dwShow |= SHOW_CACHEINFO;
break;
case 'R':
case 'r':
dwShow |= SHOW_REGINFO;
break;
case 'F':
case 'f':
dwShow |= SHOW_FILEINFO;
break;
case 'E':
case 'e':
dwShow |= SHOW_ENUMFILES;
break;
case 'A':
case 'a':
dwShow |= SHOW_ALL;
break;
default:
ShowUsage();
return;
}
}
}
if (0 == dwShow)
{
dwShow = SHOW_DEFAULT;
}
TCHAR szScratch[MAX_PATH];
TCHAR szComputer[MAX_COMPUTERNAME_LENGTH + 1];
TCHAR szDateTime[80];
_tprintf(TEXT("Status of CSC for %s (%s)\n\n"),
GetMachineName(szComputer, ARRAYSIZE(szComputer)),
GetCurrentDateTime(szDateTime, ARRAYSIZE(szDateTime)));
_tprintf(TEXT("Operating system: %s\n\n"), GetOsVersionInfoText(szScratch));
if (dwShow & SHOW_FILEINFO)
{
_tprintf(TEXT("Binary file information:\n\n"));
DumpFileInformation(TEXT("%systemroot%\\system32\\CSCDLL.DLL"));
DumpFileInformation(TEXT("%systemroot%\\system32\\CSCUI.DLL"));
}
if (dwShow & SHOW_CACHEINFO)
{
DumpCacheStats();
PrintShareStatusFlags();
}
if (dwShow & SHOW_ENUMFILES)
{
EnumFiles();
PrintFileStatusFlags();
PrintHintFlags();
}
if (dwShow & SHOW_REGINFO)
DumpRegStats();
}