|
|
#define UNICODE
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winioctl.h>
#include <shdcom.h>
#include <shellapi.h>
#include <smbdebug.h>
#include <time.h>
#include "struct.h"
#include "messages.h"
#include "cscapi.h"
CHAR *ProgName = "cscutil";
#define CSC_MERGE_KEEP_LOCAL 1
#define CSC_MERGE_KEEP_NETWORK 2
#define CSC_MERGE_KEEP_BOTH 3
//
// Arguments (ie '/arg:')
//
MAKEARG(Pin); MAKEARG(UnPin); MAKEARG(Delete); MAKEARG(DeleteShadow); MAKEARG(GetShadow); MAKEARG(GetShadowInfo); MAKEARG(ShareId); MAKEARG(Fill); MAKEARG(Db); MAKEARG(SetShareStatus); MAKEARG(Purge); MAKEARG(IsServerOffline); MAKEARG(EnumForStats); MAKEARG(SetSpace); MAKEARG(Merge); MAKEARG(QueryFile); MAKEARG(QueryFileEx); MAKEARG(QueryShare); MAKEARG(Check); MAKEARG(ExclusionList); MAKEARG(BWConservationList); MAKEARG(Disconnect); MAKEARG(Reconnect); MAKEARG(Enum); MAKEARG(Move); MAKEARG(Bitcopy); MAKEARG(RandW); MAKEARG(Offset); MAKEARG(MoveShare);
//
// Switches (ie '/arg')
//
SWITCH(Info); SWITCH(Fcblist); SWITCH(DBStatus); SWITCH(PQEnum); SWITCH(User); SWITCH(System); SWITCH(Inherit); SWITCH(Recurse); SWITCH(Abort); SWITCH(Skip); SWITCH(Ask); SWITCH(Eof); SWITCH(Retry); SWITCH(Touch); SWITCH(Enable); SWITCH(Disable); SWITCH(Ioctl); SWITCH(Flags); SWITCH(GetSpace); SWITCH(Encrypt); SWITCH(Decrypt); SWITCH(Db); SWITCH(Set); SWITCH(Clear); SWITCH(Purge); SWITCH(Detector); SWITCH(Switches);
SWITCH(Debug); SWITCH(Help); SWITCH(HelpHelp); SWITCH(Enum); SWITCH(Resid); SWITCH(Full);
//
// The macro can not make these
//
WCHAR SwQ[] = L"/?"; BOOLEAN fSwQ; WCHAR SwQQ[] = L"/??"; BOOLEAN fSwQQ;
//
// Globals
//
LPWSTR pwszDisconnectArg = NULL; LPWSTR pwszExclusionListArg = NULL; LPWSTR pwszBWConservationListArg = NULL; LPWSTR pwszSetShareStatusArg = NULL; LPWSTR pwszIsServerOfflineArg = NULL; LPWSTR pwszPurgeArg = NULL; LPWSTR pwszPinUnPinArg = NULL; LPWSTR pwszDeleteArg = NULL; LPWSTR pwszDeleteShadowArg = NULL; LPWSTR pwszGetShadowArg = NULL; LPWSTR pwszGetShadowInfoArg = NULL; LPWSTR pwszShareIdArg = NULL; LPWSTR pwszReconnectArg = NULL; LPWSTR pwszQueryFileArg = NULL; LPWSTR pwszQueryFileExArg = NULL; LPWSTR pwszDbArg = NULL; LPWSTR pwszSetSpaceArg = NULL; LPWSTR pwszQueryShareArg = NULL; LPWSTR pwszMoveArg = NULL; LPWSTR pwszMergeArg = NULL; LPWSTR pwszFillArg = NULL; LPWSTR pwszEnumArg = NULL; LPWSTR pwszRandWArg = NULL; LPWSTR pwszBitcopyArg = NULL; LPWSTR pwszOffsetArg = NULL; LPWSTR pwszEnumForStatsArg = NULL; LPWSTR pwszCheckArg = NULL;
char statusName[4][32] = { "Local Path", "Offline Share", "Online Share", "No CSC" };
DWORD Usage( BOOLEAN fHelpHelp);
BOOLEAN CmdProcessArg( LPWSTR Arg);
DWORD CmdInfo( ULONG Cmd);
DWORD CmdDBStatus( VOID);
DWORD CmdPurge( PWSTR PurgeArg);
DWORD CmdDetector( VOID);
DWORD CmdPQEnum( VOID);
DWORD CmdGetSpace( VOID);
DWORD CmdSwitches( VOID);
DWORD CmdDisconnect( PWSTR DisconnectArg);
DWORD CmdExclusionList( PWSTR ExclusionListArg);
DWORD CmdBWConservationList( PWSTR BWConservationListArg);
DWORD CmdSetShareStatus( PWSTR SetShareStatusArg);
DWORD CmdIsServerOffline( PWSTR IsServerOfflineArg);
DWORD CmdReconnect( PWSTR ReconnectArg);
DWORD CmdQueryFile( PWSTR QueryFileArg);
DWORD CmdQueryFileEx( PWSTR QueryFileExArg);
DWORD CmdDb( PWSTR DbArg);
DWORD CmdSetSpace( PWSTR SetSpaceArg);
DWORD CmdQueryShare( PWSTR QueryShareArg);
DWORD CmdMove( PWSTR MoveArg);
DWORD CmdMerge( PWSTR MergeArg);
DWORD CmdEncryptDecrypt( BOOL fEncrypt);
DWORD CmdFill( PWSTR FillArg);
DWORD CmdCheck( PWSTR CheckArg);
DWORD CmdEnum( PWSTR CmdEnumArg);
DWORD CmdRandW( PWSTR CmdRandWArg);
DWORD CmdBitcopy( PWSTR CmdBitcopyArg);
DWORD CmdEnumForStats( PWSTR EnumForStatsArg);
DWORD CmdDelete( PWSTR DeleteArg);
DWORD CmdGetShadow( PWSTR GetShadowArg);
DWORD CmdGetShadowInfo( PWSTR GetShadowInfoArg);
DWORD CmdShareId( PWSTR ShareIdArg);
DWORD CmdDeleteShadow( PWSTR DeleteArg);
DWORD CmdPinUnPin( BOOL fPin, PWSTR PinArg);
DWORD CmdMoveShare( PWSTR source, PWSTR dest);
SHARESTATUS GetCSCStatus ( const WCHAR * pwszPath);
BOOL GetShareStatus ( const WCHAR * pwszShare, DWORD * pdwStatus, DWORD * pdwPinCount, DWORD * pdwHints);
void MoveDirInCSC ( const WCHAR * pwszSource, const WCHAR * pwszDest, const WCHAR * pwszSkipSubdir, SHARESTATUS StatusFrom, SHARESTATUS StatusTo, BOOL bAllowRdrTimeoutForDel, BOOL bAllowRdrTimeoutForRen);
DWORD DoCSCRename ( const WCHAR * pwszSource, const WCHAR * pwszDest, BOOL bOverwrite, BOOL bAllowRdrTimeout);
DWORD DeleteCSCFileTree ( const WCHAR * pwszSource, const WCHAR * pwszSkipSubdir, BOOL bAllowRdrTimeout);
DWORD DeleteCSCFile ( const WCHAR * pwszPath, BOOL bAllowRdrTimeout);
DWORD DeleteCSCShareIfEmpty ( LPCTSTR pwszFileName, SHARESTATUS shStatus);
DWORD MergePinInfo ( LPCTSTR pwszSource, LPCTSTR pwszDest, SHARESTATUS StatusFrom, SHARESTATUS StatusTo);
DWORD PinIfNecessary ( const WCHAR * pwszPath, SHARESTATUS shStatus);
DWORD CscMergeFillAsk( LPCWSTR lpszFullPath);
DWORD MyCscMergeProcW( LPCWSTR lpszFullPath, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *lpFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext);
DWORD MyCscFillProcW( LPCWSTR lpszFullPath, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *lpFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext);
DWORD MyEncryptDecryptProcW( LPCWSTR lpszFullPath, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *lpFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext);
DWORD MyEnumForStatsProcW( LPCWSTR lpszFullPath, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *lpFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext);
DWORD FileStatusToEnglish( DWORD Status, LPWSTR OutputBuffer);
DWORD HintsToEnglish( DWORD Hint, LPWSTR OutputBuffer);
DWORD ShareStatusToEnglish( DWORD Status, LPWSTR OutputBuffer);
BOOLEAN LooksToBeAShare(LPWSTR Name);
LONG CountOffsetArgs( PWSTR OffsetArg, ULONG OffsetArray[]);
DWORD DumpBitMap( LPWSTR lpszTempName);
VOID ErrorMessage( IN HRESULT hr, ...);
WCHAR NameBuf[MAX_PATH + 25];
WCHAR vtzDefaultExclusionList[] = L" *.SLM *.MDB *.LDB *.MDW *.MDE *.PST *.DB?"; // from ui.c
//
// These functions were added for Windows XP, and so we do a loadlibrary on them, so that
// this utility will work on both Windows 2000 and Windows XP
//
typedef BOOL (*CSCQUERYFILESTATUSEXW)(LPCWSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD, LPDWORD); typedef BOOL (*CSCQUERYSHARESTATUSW)(LPCWSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD, LPDWORD); typedef BOOL (*CSCPURGEUNPINNEDFILES)(ULONG, PULONG, PULONG); typedef BOOL (*CSCENCRYPTDECRYPTDATABASE)(BOOL, LPCSCPROCW, DWORD_PTR); typedef BOOL (*CSCSHAREIDTOSHARENAME)(ULONG, PBYTE, PULONG);
_cdecl main(int argc, char *argv[]) { DWORD dwErr = ERROR_SUCCESS; LPWSTR CommandLine; LPWSTR *argvw; int argx; int argcw;
// fSwDebug = TRUE;
if (!CSCIsCSCEnabled()) { Usage(FALSE); ErrorMessage(MSG_CSC_DISABLED); return 1; } //
// Get the command line in Unicode
//
CommandLine = GetCommandLine();
argvw = CommandLineToArgvW(CommandLine, &argcw);
if ( argvw == NULL ) { MyPrintf(L"cscutil:Can't convert command line to Unicode: %d\r\n", GetLastError() ); return 1; }
//
// Get the arguments
//
if (argcw <= 1) { Usage(FALSE); dwErr = ERROR_SUCCESS; goto Cleanup; }
//
// Process arguments
//
for (argx = 1; argx < argcw; argx++) { if (CmdProcessArg(argvw[argx]) != TRUE) { dwErr = ERROR_INVALID_PARAMETER; goto Cleanup; } if (fArgMoveShare) { break; } }
if (fSwDebug == TRUE) { MyPrintf(L"Do special debug stuff here\r\n"); }
//
// Do the work
//
if (fSwHelp == TRUE || fSwQ == TRUE) { dwErr = Usage(FALSE); } else if (fSwHelpHelp == TRUE || fSwQQ == TRUE) { dwErr = Usage(TRUE); } else if (fSwInfo == TRUE) { dwErr = CmdInfo(DEBUG_INFO_SERVERLIST); } else if (fSwFcblist == TRUE) { dwErr = CmdInfo(DEBUG_INFO_CSCFCBSLIST); } else if (fSwGetSpace == TRUE) { dwErr = CmdGetSpace(); } else if (fSwDBStatus == TRUE) { dwErr = CmdDBStatus(); } else if (fArgPurge == TRUE) { dwErr = CmdPurge(pwszPurgeArg); } else if (fSwPurge == TRUE) { dwErr = CmdPurge(NULL); } else if (fSwDetector == TRUE) { dwErr = CmdDetector(); } else if (fSwPQEnum == TRUE) { dwErr = CmdPQEnum(); } else if (fSwFlags == TRUE) { ErrorMessage(MSG_FLAGS); dwErr = ERROR_SUCCESS; } else if (fSwEnable == TRUE) { dwErr = (CSCDoEnableDisable(TRUE) == TRUE) ? ERROR_SUCCESS : GetLastError(); } else if (fSwDisable == TRUE) { dwErr = (CSCDoEnableDisable(FALSE) == TRUE) ? ERROR_SUCCESS : GetLastError(); } else if (fSwSwitches == TRUE) { dwErr = CmdSwitches(); } else if (fArgDisconnect == TRUE) { dwErr = CmdDisconnect(pwszDisconnectArg); } else if (fArgExclusionList == TRUE) { dwErr = CmdExclusionList(pwszExclusionListArg); } else if (fArgBWConservationList == TRUE) { dwErr = CmdBWConservationList(pwszBWConservationListArg); } else if (fArgSetShareStatus == TRUE) { dwErr = CmdSetShareStatus(pwszSetShareStatusArg); } else if (fArgIsServerOffline == TRUE) { dwErr = CmdIsServerOffline(pwszIsServerOfflineArg); } else if (fArgReconnect == TRUE) { dwErr = CmdReconnect(pwszReconnectArg); } else if (fArgQueryFile == TRUE) { dwErr = CmdQueryFile(pwszQueryFileArg); } else if (fArgQueryFileEx == TRUE) { dwErr = CmdQueryFileEx(pwszQueryFileExArg); #if defined(CSCUTIL_INTERNAL)
} else if (fArgDb == TRUE) { dwErr = CmdDb(pwszDbArg); } else if (fSwDb == TRUE) { dwErr = CmdDb(NULL); } else if (fArgBitcopy == TRUE) { dwErr = CmdBitcopy(pwszBitcopyArg); #endif // CSCUTIL_INTERNAL
} else if (fArgSetSpace == TRUE) { dwErr = CmdSetSpace(pwszSetSpaceArg); } else if (fArgQueryShare == TRUE) { dwErr = CmdQueryShare(pwszQueryShareArg); } else if (fArgMerge == TRUE) { dwErr = CmdMerge(pwszMergeArg); } else if (fArgMove == TRUE) { dwErr = CmdMove(pwszMoveArg); } else if (fSwEncrypt == TRUE) { dwErr = CmdEncryptDecrypt(TRUE); } else if (fSwDecrypt == TRUE) { dwErr = CmdEncryptDecrypt(FALSE); } else if (fArgFill == TRUE) { dwErr = CmdFill(pwszFillArg); } else if (fArgCheck == TRUE) { dwErr = CmdCheck(pwszCheckArg); } else if (fArgEnum == TRUE) { dwErr = CmdEnum(pwszEnumArg); } else if (fSwEnum == TRUE) { dwErr = CmdEnum(NULL); } else if (fArgRandW == TRUE) { dwErr = CmdRandW(pwszRandWArg); } else if (fArgEnumForStats == TRUE) { dwErr = CmdEnumForStats(pwszEnumForStatsArg); } else if (fArgGetShadow == TRUE) { dwErr = CmdGetShadow(pwszGetShadowArg); } else if (fArgGetShadowInfo == TRUE) { dwErr = CmdGetShadowInfo(pwszGetShadowInfoArg); } else if (fArgShareId == TRUE) { dwErr = CmdShareId(pwszShareIdArg); } else if (fArgDelete == TRUE) { dwErr = CmdDelete(pwszDeleteArg); } else if (fArgDeleteShadow == TRUE) { dwErr = CmdDeleteShadow(pwszDeleteShadowArg); } else if (fArgPin == TRUE || fArgUnPin == TRUE) { dwErr = CmdPinUnPin(fArgPin, pwszPinUnPinArg); } else if (fArgMoveShare == TRUE) { if (argcw == 4) { dwErr = CmdMoveShare(argvw[2], argvw[3]); } else { dwErr = Usage(FALSE); dwErr = ERROR_INVALID_PARAMETER; } } else { dwErr = Usage(FALSE); }
Cleanup:
if (dwErr == ERROR_SUCCESS) { ErrorMessage(MSG_SUCCESSFUL); } else { LPWSTR MessageBuffer; DWORD dwBufferLength;
dwBufferLength = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &MessageBuffer, 0, NULL);
ErrorMessage(MSG_ERROR, dwErr); if (dwBufferLength > 0) { MyPrintf(L"%ws\r\n", MessageBuffer); LocalFree(MessageBuffer); } }
return dwErr; }
BOOLEAN CmdProcessArg(LPWSTR Arg) { LONG ArgLen; BOOLEAN dwErr = FALSE; BOOLEAN FoundAnArg = FALSE;
if (fSwDebug == TRUE) MyPrintf(L"ProcessArg(%ws)\r\n", Arg);
if ( Arg != NULL && wcslen(Arg) > 1) {
dwErr = TRUE; ArgLen = wcslen(Arg);
//
// Commands with args
//
if (_wcsnicmp(Arg, ArgDisconnect, ArgLenDisconnect) == 0) { FoundAnArg = fArgDisconnect = TRUE; if (ArgLen > ArgLenDisconnect) pwszDisconnectArg = &Arg[ArgLenDisconnect]; } else if (_wcsnicmp(Arg, ArgEnum, ArgLenEnum) == 0) { FoundAnArg = fArgEnum = TRUE; if (ArgLen > ArgLenEnum) pwszEnumArg = &Arg[ArgLenEnum]; } else if (_wcsnicmp(Arg, ArgMoveShare, ArgLenMoveShare) == 0) { FoundAnArg = fArgMoveShare = TRUE; #if defined(CSCUTIL_INTERNAL)
} else if (_wcsnicmp(Arg, ArgReconnect, ArgLenReconnect) == 0) { FoundAnArg = fArgReconnect = TRUE; if (ArgLen > ArgLenReconnect) pwszReconnectArg = &Arg[ArgLenReconnect]; } else if (_wcsnicmp(Arg, ArgPin, ArgLenPin) == 0) { FoundAnArg = fArgPin = TRUE; if (ArgLen > ArgLenPin) pwszPinUnPinArg = &Arg[ArgLenPin]; } else if (_wcsnicmp(Arg, ArgUnPin, ArgLenUnPin) == 0) { FoundAnArg = fArgUnPin = TRUE; if (ArgLen > ArgLenUnPin) pwszPinUnPinArg = &Arg[ArgLenUnPin]; } else if (_wcsnicmp(Arg, ArgDelete, ArgLenDelete) == 0) { FoundAnArg = fArgDelete = TRUE; if (ArgLen > ArgLenDelete) pwszDeleteArg = &Arg[ArgLenDelete]; } else if (_wcsnicmp(Arg, ArgExclusionList, ArgLenExclusionList) == 0) { FoundAnArg = fArgExclusionList = TRUE; if (ArgLen > ArgLenExclusionList) pwszExclusionListArg = &Arg[ArgLenExclusionList]; } else if (_wcsnicmp(Arg, ArgBWConservationList, ArgLenBWConservationList) == 0) { FoundAnArg = fArgBWConservationList = TRUE; if (ArgLen > ArgLenBWConservationList) pwszBWConservationListArg = &Arg[ArgLenBWConservationList]; } else if (_wcsnicmp(Arg, ArgSetShareStatus, ArgLenSetShareStatus) == 0) { FoundAnArg = fArgSetShareStatus = TRUE; if (ArgLen > ArgLenSetShareStatus) pwszSetShareStatusArg = &Arg[ArgLenSetShareStatus]; } else if (_wcsnicmp(Arg, ArgIsServerOffline, ArgLenIsServerOffline) == 0) { FoundAnArg = fArgIsServerOffline = TRUE; if (ArgLen > ArgLenIsServerOffline) pwszIsServerOfflineArg = &Arg[ArgLenIsServerOffline]; } else if (_wcsnicmp(Arg, ArgPurge, ArgLenPurge) == 0) { FoundAnArg = fArgPurge = TRUE; if (ArgLen > ArgLenPurge) pwszPurgeArg = &Arg[ArgLenPurge]; } else if (_wcsnicmp(Arg, ArgRandW, ArgLenRandW) == 0) { FoundAnArg = fArgRandW = TRUE; if (ArgLen > ArgLenRandW) pwszRandWArg = &Arg[ArgLenRandW]; } else if (_wcsnicmp(Arg, ArgBitcopy, ArgLenBitcopy) == 0) { FoundAnArg = fArgBitcopy = TRUE; if (ArgLen > ArgLenBitcopy) pwszBitcopyArg = &Arg[ArgLenBitcopy]; } else if (_wcsnicmp(Arg, ArgOffset, ArgLenOffset) == 0) { FoundAnArg = fArgOffset = TRUE; if (ArgLen > ArgLenOffset) pwszOffsetArg = &Arg[ArgLenOffset]; } else if (_wcsnicmp(Arg, ArgDeleteShadow, ArgLenDeleteShadow) == 0) { FoundAnArg = fArgDeleteShadow = TRUE; if (ArgLen > ArgLenDeleteShadow) pwszDeleteShadowArg = &Arg[ArgLenDeleteShadow]; } else if (_wcsnicmp(Arg, ArgQueryFile, ArgLenQueryFile) == 0) { FoundAnArg = fArgQueryFile = TRUE; if (ArgLen > ArgLenQueryFile) pwszQueryFileArg = &Arg[ArgLenQueryFile]; } else if (_wcsnicmp(Arg, ArgQueryFileEx, ArgLenQueryFileEx) == 0) { FoundAnArg = fArgQueryFileEx = TRUE; if (ArgLen > ArgLenQueryFileEx) pwszQueryFileExArg = &Arg[ArgLenQueryFileEx]; } else if (_wcsnicmp(Arg, ArgDb, ArgLenDb) == 0) { FoundAnArg = fArgDb = TRUE; if (ArgLen > ArgLenDb) pwszDbArg = &Arg[ArgLenDb]; } else if (_wcsnicmp(Arg, ArgSetSpace, ArgLenSetSpace) == 0) { FoundAnArg = fArgSetSpace = TRUE; if (ArgLen > ArgLenSetSpace) pwszSetSpaceArg = &Arg[ArgLenSetSpace]; } else if (_wcsnicmp(Arg, ArgGetShadow, ArgLenGetShadow) == 0) { FoundAnArg = fArgGetShadow = TRUE; if (ArgLen > ArgLenGetShadow) pwszGetShadowArg = &Arg[ArgLenGetShadow]; } else if (_wcsnicmp(Arg, ArgGetShadowInfo, ArgLenGetShadowInfo) == 0) { FoundAnArg = fArgGetShadowInfo = TRUE; if (ArgLen > ArgLenGetShadowInfo) pwszGetShadowInfoArg = &Arg[ArgLenGetShadowInfo]; } else if (_wcsnicmp(Arg, ArgShareId, ArgLenShareId) == 0) { FoundAnArg = fArgShareId = TRUE; if (ArgLen > ArgLenShareId) pwszShareIdArg = &Arg[ArgLenShareId]; } else if (_wcsnicmp(Arg, ArgQueryShare, ArgLenQueryShare) == 0) { FoundAnArg = fArgQueryShare = TRUE; if (ArgLen > ArgLenQueryShare) pwszQueryShareArg = &Arg[ArgLenQueryShare]; } else if (_wcsnicmp(Arg, ArgMove, ArgLenMove) == 0) { FoundAnArg = fArgMove = TRUE; if (ArgLen > ArgLenMove) pwszMoveArg = &Arg[ArgLenMove]; } else if (_wcsnicmp(Arg, ArgMerge, ArgLenMerge) == 0) { FoundAnArg = fArgMerge = TRUE; if (ArgLen > ArgLenMerge) pwszMergeArg = &Arg[ArgLenMerge]; } else if (_wcsnicmp(Arg, ArgFill, ArgLenFill) == 0) { FoundAnArg = fArgFill = TRUE; if (ArgLen > ArgLenFill) pwszFillArg = &Arg[ArgLenFill]; } else if (_wcsnicmp(Arg, ArgCheck, ArgLenCheck) == 0) { FoundAnArg = fArgCheck = TRUE; if (ArgLen > ArgLenCheck) pwszCheckArg = &Arg[ArgLenCheck]; } else if (_wcsnicmp(Arg, ArgEnumForStats, ArgLenEnumForStats) == 0) { FoundAnArg = fArgEnumForStats = TRUE; if (ArgLen > ArgLenEnumForStats) pwszEnumForStatsArg = &Arg[ArgLenEnumForStats]; #endif // CSCUTIL_INTERNAL
}
// Switches go at the end!!
if (_wcsicmp(Arg, SwHelp) == 0) { FoundAnArg = fSwHelp = TRUE; } else if (_wcsicmp(Arg, SwResid) == 0) { FoundAnArg = fSwTouch = fSwEnum = fSwRecurse = TRUE; } else if (_wcsicmp(Arg, SwFull) == 0) { FoundAnArg = fSwFull = TRUE; } else if (_wcsicmp(Arg, SwTouch) == 0) { FoundAnArg = fSwTouch = TRUE; } else if (_wcsicmp(Arg, SwEnum) == 0) { FoundAnArg = fSwEnum = TRUE; } else if (_wcsicmp(Arg, SwQQ) == 0) { FoundAnArg = fSwQQ = TRUE; } else if (_wcsicmp(Arg, SwQ) == 0) { FoundAnArg = fSwQ = TRUE; } else if (_wcsicmp(Arg, SwRecurse) == 0) { FoundAnArg = fSwRecurse = TRUE; #if defined(CSCUTIL_INTERNAL)
} else if (_wcsicmp(Arg, SwDebug) == 0) { FoundAnArg = fSwDebug = TRUE; } else if (_wcsicmp(Arg, SwHelpHelp) == 0) { FoundAnArg = fSwHelpHelp = TRUE; } else if (_wcsicmp(Arg, SwPQEnum) == 0) { FoundAnArg = fSwPQEnum = TRUE; } else if (_wcsicmp(Arg, SwInfo) == 0) { FoundAnArg = fSwInfo = TRUE; } else if (_wcsicmp(Arg, SwDBStatus) == 0) { FoundAnArg = fSwDBStatus = TRUE; } else if (_wcsicmp(Arg, SwPurge) == 0) { FoundAnArg = fSwPurge = TRUE; } else if (_wcsicmp(Arg, SwDetector) == 0) { FoundAnArg = fSwDetector = TRUE; } else if (_wcsicmp(Arg, SwGetSpace) == 0) { FoundAnArg = fSwGetSpace = TRUE; } else if (_wcsicmp(Arg, SwDb) == 0) { FoundAnArg = fSwDb = TRUE; } else if (_wcsicmp(Arg, SwFcblist) == 0) { FoundAnArg = fSwFcblist = TRUE; } else if (_wcsicmp(Arg, SwEnable) == 0) { FoundAnArg = fSwEnable = TRUE; } else if (_wcsicmp(Arg, SwDisable) == 0) { FoundAnArg = fSwDisable = TRUE; } else if (_wcsicmp(Arg, SwSwitches) == 0) { FoundAnArg = fSwSwitches = TRUE; } else if (_wcsicmp(Arg, SwUser) == 0) { FoundAnArg = fSwUser = TRUE; } else if (_wcsicmp(Arg, SwSystem) == 0) { FoundAnArg = fSwSystem = TRUE; } else if (_wcsicmp(Arg, SwInherit) == 0) { FoundAnArg = fSwInherit = TRUE; } else if (_wcsicmp(Arg, SwAbort) == 0) { FoundAnArg = fSwAbort = TRUE; } else if (_wcsicmp(Arg, SwSkip) == 0) { FoundAnArg = fSwSkip = TRUE; } else if (_wcsicmp(Arg, SwAsk) == 0) { FoundAnArg = fSwAsk = TRUE; } else if (_wcsicmp(Arg, SwEof) == 0) { FoundAnArg = fSwEof = TRUE; } else if (_wcsicmp(Arg, SwRetry) == 0) { FoundAnArg = fSwRetry = TRUE; } else if (_wcsicmp(Arg, SwSet) == 0) { FoundAnArg = fSwSet = TRUE; } else if (_wcsicmp(Arg, SwClear) == 0) { FoundAnArg = fSwClear = TRUE; } else if (_wcsicmp(Arg, SwFlags) == 0) { FoundAnArg = fSwFlags = TRUE; } else if (_wcsicmp(Arg, SwIoctl) == 0) { FoundAnArg = fSwIoctl = TRUE; } else if (_wcsicmp(Arg, SwEncrypt) == 0) { FoundAnArg = fSwEncrypt = TRUE; } else if (_wcsicmp(Arg, SwDecrypt) == 0) { FoundAnArg = fSwDecrypt = TRUE; #endif // CSCUTIL_INTERNAL
}
if (FoundAnArg == FALSE) { ErrorMessage(MSG_UNRECOGNIZED_OPTION, &Arg[1]); dwErr = FALSE; goto AllDone; }
}
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"ProcessArg exit %d\r\n", dwErr);
return dwErr; }
DWORD Usage( BOOLEAN fHelpHelp) { #if defined(CSCUTIL_INTERNAL)
ErrorMessage(MSG_USAGE); if (fHelpHelp == TRUE) ErrorMessage(MSG_USAGE_EX); #else
ErrorMessage(MSG_USAGE2); if (fHelpHelp == TRUE) ErrorMessage(MSG_USAGE_EX2); #endif // CSCUTIL_INTERNAL
return ERROR_SUCCESS; }
DWORD CmdMoveShare( PWSTR source, PWSTR dest) { SHARESTATUS sFrom, sTo;
//printf( "Attempting move from %ws to %ws.\n", source, dest );
sFrom = GetCSCStatus(source); //printf( "INFO: %ws status = %s\n", source, statusName[sFrom] );
sTo = GetCSCStatus(dest); //printf( "INFO: %ws status = %s\n", dest, statusName[sTo] );
// Check and make sure this is valid
if( (sFrom == PathLocal) || (sTo == PathLocal) ) { ErrorMessage(MSG_TO_LOCAL); return ERROR_INVALID_PARAMETER; }
if( (sFrom == NoCSC) || (sTo == NoCSC) ) { ErrorMessage(MSG_NO_CSC); return ERROR_INVALID_PARAMETER; }
if( sTo == ShareOffline ) { ErrorMessage(MSG_NOT_ONLINE); return ERROR_CSCSHARE_OFFLINE; }
MoveDirInCSC( source, dest, NULL, ShareOnline, ShareOnline, TRUE, TRUE );
return ERROR_SUCCESS; }
//+--------------------------------------------------------------------------
//
// Function: MoveDirInCSC
//
// Synopsis: this function moves a directory within the CSC cache without
// prejudice. If the destination is a local path, it just deletes
// the source tree from the cache
//
// Arguments: [in] pwszSource : the source path
// [in] pwszDest : the dest path
// [in] pwszSkipSubdir : the directory to skip while moving
// [in] StatusFrom : the CSC status of the source path
// [in] StatusTo : the CSC status of the dest. path
// [in] bAllowRdrTimeout : if stuff needs to be deleted from the
// cache, we may not succeed immediately since
// the rdr keeps the handles to recently opened
// files open. This paramaters tells the function
// whether it needs to wait and retry
//
// Returns: nothing. it just tries its best.
//
// History: 11/21/1998 RahulTh created
//
// Notes: the value of bAllowRdrTimeout is always ignored for the
// in-cache rename operation. we always want to wait for
// the timeout.
//
//---------------------------------------------------------------------------
void MoveDirInCSC (const WCHAR * pwszSource, const WCHAR * pwszDest, const WCHAR * pwszSkipSubdir, SHARESTATUS StatusFrom, SHARESTATUS StatusTo, BOOL bAllowRdrTimeoutForDel, BOOL bAllowRdrTimeoutForRen) { WIN32_FIND_DATA findData; DWORD dwFileStatus; DWORD dwPinCount; HANDLE hCSCFind; DWORD dwHintFlags; FILETIME origTime; WCHAR * pwszPath; WCHAR * pwszEnd; int len; DWORD StatusCSCRen = ERROR_SUCCESS;
if (PathLocal == StatusFrom) return; //there is nothing to do. nothing was cached.
if (PathLocal == StatusTo) { //the destination is a local path, so we should just delete the
//files from the source
DeleteCSCFileTree (pwszSource, pwszSkipSubdir, bAllowRdrTimeoutForDel); } else { pwszPath = (WCHAR *) malloc (sizeof (WCHAR) * ((len = wcslen (pwszSource)) + MAX_PATH + 2)); if (!pwszPath || len <= 0) return; wcscpy (pwszPath, pwszSource); pwszEnd = pwszPath + len; if (L'\\' != pwszEnd[-1]) { *pwszEnd++ = L'\\'; } hCSCFind = CSCFindFirstFile (pwszSource, &findData, &dwFileStatus, &dwPinCount, &dwHintFlags, &origTime);
if (INVALID_HANDLE_VALUE != hCSCFind) { do { if (0 != _wcsicmp (L".", findData.cFileName) && 0 != _wcsicmp (L"..", findData.cFileName) && (!pwszSkipSubdir || (0 != _wcsicmp (findData.cFileName, pwszSkipSubdir)))) { wcscpy (pwszEnd, findData.cFileName); if (ERROR_SUCCESS == StatusCSCRen) { StatusCSCRen = DoCSCRename (pwszPath, pwszDest, TRUE, bAllowRdrTimeoutForRen); } else { StatusCSCRen = DoCSCRename (pwszPath, pwszDest, TRUE, FALSE); } }
} while ( CSCFindNextFile (hCSCFind, &findData, &dwFileStatus, &dwPinCount, &dwHintFlags, &origTime) );
CSCFindClose (hCSCFind); }
//merge the pin info. at the top level folder
MergePinInfo (pwszSource, pwszDest, StatusFrom, StatusTo); //remove the share - Navjot.
if (!CSCDeleteW(pwszSource)) StatusCSCRen = GetLastError(); }
return; }
//+--------------------------------------------------------------------------
//
// Function: DoCSCRename
//
// Synopsis: does a file rename within the CSC cache.
//
// Arguments: [in] pwszSource : full source path
// [in] pwszDest : full path to destination directory
// [in] bOverwrite : overwrite if the file/folder exists at
// the destination
// [in] bAllowRdrTimeout : if TRUE, retry for 10 seconds on failure
// so that rdr and mem. mgr. get enough time to
// release the handles.
//
// Returns: ERROR_SUCCESS if the rename was successful.
// an error code otherwise.
//
// History: 5/26/1999 RahulTh created
//
// Notes: no validation of parameters is done. The caller is responsible
// for that
//
//---------------------------------------------------------------------------
DWORD DoCSCRename (const WCHAR * pwszSource, const WCHAR * pwszDest, BOOL bOverwrite, BOOL bAllowRdrTimeout) { DWORD Status = ERROR_SUCCESS; BOOL bStatus; int i;
bStatus = CSCDoLocalRename (pwszSource, pwszDest, bOverwrite); if (!bStatus) { Status = GetLastError(); if (ERROR_SUCCESS != Status && ERROR_FILE_NOT_FOUND != Status && ERROR_PATH_NOT_FOUND != Status && ERROR_INVALID_PARAMETER != Status && ERROR_BAD_NETPATH != Status) { if (bAllowRdrTimeout) { if (!bOverwrite && ERROR_FILE_EXISTS == Status) { Status = ERROR_SUCCESS; } else { for (i = 0; i < 11; i++) { Sleep (1000); //wait for the handle to be released
bStatus = CSCDoLocalRename (pwszSource, pwszDest, bOverwrite); if (bStatus) { Status = ERROR_SUCCESS; break; } } } } } else { Status = ERROR_SUCCESS; } }
return Status; }
//+--------------------------------------------------------------------------
//
// Function: DeleteCSCFileTree
//
// Synopsis: deletes a file tree from the CSC
//
// Arguments: [in] pwszSource : the path to the folder whose contents should
// be deleted
// [in] pwszSkipSubdir : name of the subdirectory to be skipped.
// [in] bAllowRdrTimeout : if true, makes multiple attempts to
// delete the file since the rdr may have left
// the handle open for sometime which can result
// in an ACCESS_DENIED message.
//
// Returns: ERROR_SUCCESS if the deletion was successful. An error code
// otherwise.
//
// History: 11/21/1998 RahulTh created
//
// Notes:
//
//---------------------------------------------------------------------------
DWORD DeleteCSCFileTree (const WCHAR * pwszSource, const WCHAR * pwszSkipSubdir, BOOL bAllowRdrTimeout) { WIN32_FIND_DATA findData; DWORD dwFileStatus; DWORD dwPinCount; HANDLE hCSCFind; DWORD dwHintFlags; FILETIME origTime; WCHAR * pwszPath; WCHAR * pwszEnd; int len; DWORD Status = ERROR_SUCCESS;
pwszPath = (WCHAR *) malloc (sizeof(WCHAR) * ((len = wcslen(pwszSource)) + MAX_PATH + 2)); if (!pwszPath) return ERROR_OUTOFMEMORY; //nothing much we can do if we run out of memory
if (len <= 0) return ERROR_BAD_PATHNAME;
wcscpy (pwszPath, pwszSource); pwszEnd = pwszPath + len; if (L'\\' != pwszEnd[-1]) { *pwszEnd++ = L'\\'; }
hCSCFind = CSCFindFirstFile (pwszSource, &findData, &dwFileStatus, &dwPinCount, &dwHintFlags, &origTime);
if (INVALID_HANDLE_VALUE != hCSCFind) { do { if (0 != _wcsicmp (L".", findData.cFileName) && 0 != _wcsicmp (L"..", findData.cFileName) && (!pwszSkipSubdir || (0 != _wcsicmp (pwszSkipSubdir, findData.cFileName)))) { wcscpy (pwszEnd, findData.cFileName);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (ERROR_SUCCESS != Status) { //no point delaying the deletes since a delete has already
//failed.
DeleteCSCFileTree (pwszPath, NULL, FALSE); } else { Status = DeleteCSCFileTree (pwszPath, NULL, bAllowRdrTimeout); } } else { if (ERROR_SUCCESS != Status) { //no point delaying the delete if we have already failed.
DeleteCSCFile (pwszPath, FALSE); } else { Status = DeleteCSCFile (pwszPath, bAllowRdrTimeout); } } }
} while ( CSCFindNextFile (hCSCFind, &findData, &dwFileStatus, &dwPinCount, &dwHintFlags, &origTime) );
CSCFindClose (hCSCFind); }
if (ERROR_SUCCESS != Status) { //no point in delaying the delete if we have already failed.
DeleteCSCFile (pwszSource, FALSE); } else { Status = DeleteCSCFile (pwszSource, bAllowRdrTimeout); }
return Status; }
//+--------------------------------------------------------------------------
//
// Function: DeleteCSCFile
//
// Synopsis: deletes the given path. but might make repeated attempts to
// make sure that the rdr has enough time to release any handles
// that it holds.
//
// Arguments: [in] pwszPath : the path to delete.
// [in] bAllowRdrTimeout : make multiple attempts to delete the
// file with waits in between so that the rdr has
// enough time to release any held handles.
//
// Returns: ERROR_SUCCES if the delete was successful. An error code
// otherwise.
//
// History: 5/26/1999 RahulTh created
//
// Notes:
//
//---------------------------------------------------------------------------
DWORD DeleteCSCFile (const WCHAR * pwszPath, BOOL bAllowRdrTimeout) { BOOL bStatus; DWORD Status = ERROR_SUCCESS; int i;
bStatus = CSCDelete (pwszPath); if (!bStatus) { Status = GetLastError(); if (ERROR_SUCCESS != Status && ERROR_FILE_NOT_FOUND != Status && ERROR_PATH_NOT_FOUND != Status && ERROR_INVALID_PARAMETER != Status) { //this is a valid error.
//so based on the value of bAllowRdrTimeout and based
//on whether we have already failed in deleting something
//we will try repeatedly to delete the file for 10 seconds
if (bAllowRdrTimeout) { for (i = 0; i < 11; i++) { Sleep (1000); //wait for 1 second and try again
bStatus = CSCDelete (pwszPath); if (bStatus) { Status = ERROR_SUCCESS; break; } } } } else { Status = ERROR_SUCCESS; } }
return Status; }
//+--------------------------------------------------------------------------
//
// Function: DeleteCSCShareIfEmpty
//
// Synopsis: given a file name, this function deletes from the local cache
// the share to which the file belongs if the local cache for that
// share is empty
//
// Arguments: [in] pwszFileName : the full file name -- must be UNC
// [in] shStatus : the share status - online, offline, local etc.
//
// Returns: ERROR_SUCCESS : if successful
// a win32 error code if something goes wrong
//
// History: 4/22/1999 RahulTh created
//
// Notes: we do not have to explicitly check if the share is empty
// because if it is not, then the delete will fail anyway
//
//---------------------------------------------------------------------------
DWORD DeleteCSCShareIfEmpty (LPCTSTR pwszFileName, SHARESTATUS shStatus) { DWORD Status; WCHAR * pwszFullPath = NULL; WCHAR * pwszCurr = NULL; int len; WCHAR * pwszShrEnd;
if (PathLocal == shStatus || NoCSC == shStatus) return ERROR_SUCCESS;
if (ShareOffline == shStatus) return ERROR_FILE_OFFLINE;
len = wcslen (pwszFileName);
if (len <= 2) return ERROR_BAD_PATHNAME;
if (pwszFileName[0] != L'\\' || pwszFileName[1] != L'\\') return ERROR_BAD_PATHNAME;
pwszFullPath = (WCHAR *) malloc (sizeof (WCHAR) * (len + 1)); if (NULL == pwszFullPath) return ERROR_OUTOFMEMORY;
if (NULL == _wfullpath(pwszFullPath, pwszFileName, len + 1)) return ERROR_BAD_PATHNAME; //canonicalization was unsuccessful.
// -- rarely happens
pwszShrEnd = wcschr (pwszFullPath + 2, L'\\');
if (NULL == pwszShrEnd) return ERROR_BAD_PATHNAME; //the path does not have the share component
pwszShrEnd++;
pwszShrEnd = wcschr (pwszShrEnd, L'\\');
if (NULL == pwszShrEnd) { //we already have the path in \\server\share form, so just try to
//delete the share.
if (!CSCDelete (pwszFullPath)) return GetLastError(); }
//if we are here, then we have a path longer than just \\server\share.
//so try to delete all the way up to the share name. This is necessary
//because a user might be redirected to something like
// \\server\share\folder\%username% and we wouldn't want only \\server\share
// and \\server\share\folder to be cached.
Status = ERROR_SUCCESS; do { pwszCurr = wcsrchr (pwszFullPath, L'\\'); if (NULL == pwszCurr) break; *pwszCurr = L'\0'; if (!CSCDelete (pwszFullPath)) { Status = GetLastError(); if (ERROR_SUCCESS == Status || ERROR_INVALID_PARAMETER == Status || ERROR_FILE_NOT_FOUND == Status || ERROR_PATH_NOT_FOUND == Status) { Status = ERROR_SUCCESS; } } if (ERROR_SUCCESS != Status) break; } while ( pwszCurr > pwszShrEnd );
return Status; }
//+--------------------------------------------------------------------------
//
// Function: MergePinInfo
//
// Synopsis: merges the pin info. from the source to destination
//
// Arguments: [in] pwszSource : the full path to the source
// [in] pwszDest : the full path to the destination
// [in] StatusFrom : CSC status of the source share
// [in] StatusTo : CSC status of the destination share
//
// Returns: ERROR_SUCCESS : if it was successful
// a Win32 error code otherwise
//
// History: 4/23/1999 RahulTh created
//
// Notes: the hint flags are a union of the source hint flags and
// destination hint flags. The pin count is the greater of the
// source and destination pin count
//
// Usually this function should only be called for folders. The
// CSC rename API handles files well. But this function will work
// for files as well.
//
//---------------------------------------------------------------------------
DWORD MergePinInfo (LPCTSTR pwszSource, LPCTSTR pwszDest, SHARESTATUS StatusFrom, SHARESTATUS StatusTo) { BOOL bStatus; DWORD dwSourceStat, dwDestStat; DWORD dwSourcePinCount, dwDestPinCount; DWORD dwSourceHints, dwDestHints; DWORD Status = ERROR_SUCCESS; DWORD i;
if (ShareOffline == StatusFrom || ShareOffline == StatusTo) return ERROR_FILE_OFFLINE;
if (ShareOnline != StatusFrom || ShareOnline != StatusTo) return ERROR_SUCCESS; //there is nothing to do if one of the shares
//is local.
if (!pwszSource || !pwszDest || 0 == wcslen(pwszSource) || 0 == wcslen(pwszDest)) return ERROR_BAD_PATHNAME;
bStatus = CSCQueryFileStatus (pwszSource, &dwSourceStat, &dwSourcePinCount, &dwSourceHints); if (!bStatus) return GetLastError();
bStatus = CSCQueryFileStatus (pwszDest, &dwDestStat, &dwDestPinCount, &dwDestHints); if (!bStatus) return GetLastError();
//first set the hint flags on the destination
if (dwDestHints != dwSourceHints) { bStatus = CSCPinFile (pwszDest, dwSourceHints, &dwDestStat, &dwDestPinCount, &dwDestHints); if (!bStatus) Status = GetLastError(); //note: we do not bail out here. we try
//to at least merge the pin count before
//leaving
}
//now merge the pin count : there is nothing to be done if the destination
//pin count is greater than or equal to the source pin count
if (dwDestPinCount < dwSourcePinCount) { for (i = 0, bStatus = TRUE; i < (dwSourcePinCount - dwDestPinCount) && bStatus; i++) { bStatus = CSCPinFile( pwszDest, FLAG_CSC_HINT_COMMAND_ALTER_PIN_COUNT, NULL, NULL, NULL ); }
if (!bStatus && ERROR_SUCCESS == Status) Status = GetLastError(); }
return Status; }
//+--------------------------------------------------------------------------
//
// Function: PinIfNecessary
//
// Synopsis: this function pins a file if necessary.
//
// Arguments: [in] pwszPath : full path of the file/folder to be pinned
// [in] shStatus : CSC status of the share.
//
// Returns: ERROR_SUCCESS if it was successful. An error code otherwise.
//
// History: 5/27/1999 RahulTh created
//
// Notes:
//
//---------------------------------------------------------------------------
DWORD PinIfNecessary (const WCHAR * pwszPath, SHARESTATUS shStatus) { DWORD Status = ERROR_SUCCESS; BOOL bStatus; DWORD dwStatus; DWORD dwPinCount; DWORD dwHints;
if (!pwszPath || !pwszPath[0]) return ERROR_BAD_NETPATH;
if (ShareOffline == shStatus) return ERROR_FILE_OFFLINE; else if (PathLocal == shStatus || NoCSC == shStatus) return ERROR_SUCCESS;
bStatus = CSCQueryFileStatus (pwszPath, &dwStatus, &dwPinCount, &dwHints); if (!bStatus || dwPinCount <= 0) { bStatus = CSCPinFile (pwszPath, FLAG_CSC_HINT_COMMAND_ALTER_PIN_COUNT, NULL, NULL, NULL); if (!bStatus) Status = GetLastError(); }
return Status; }
//+--------------------------------------------------------------------------
//
// Function: GetCSCStatus
//
// Synopsis: given a path, finds out if it is local and if it is not
// whether it is online or offline.
//
// Arguments: [in] pwszPath : the path to the file
//
// Returns: Local/Online/Offline
//
// History: 11/20/1998 RahulTh created
//
// Notes: it is important that the path passed to this function is a
// a full path and not a relative path
//
// this function will return offline if the share is not live or
// if the share is live but CSC thinks that it is offline
//
// it will return PathLocal if the path is local or if the path
// is a network path that cannot be handled by CSC e.g. a network
// share with a pathname longer than what csc can handle or if it
// is a netware share. in this case it makes sense to return
// PathLocal because CSC won't maintain a database for these shares
// -- same as for a local path. so as far as CSC is concerned, this
// is as good as a local path.
//
//---------------------------------------------------------------------------
SHARESTATUS GetCSCStatus (const WCHAR * pwszPath) { WCHAR * pwszAbsPath = NULL; WCHAR * pwszCurr = NULL; int len; BOOL bRetVal; DWORD Status; DWORD dwPinCount; DWORD dwHints;
if (!pwszPath) return ShareOffline; //a path must be provided
len = wcslen (pwszPath);
pwszAbsPath = (WCHAR *) malloc (sizeof (WCHAR) * (len + 1));
if (!pwszAbsPath) { //we are out of memory, so it is safest to return ShareOffline
//so that we can bail out of redirection.
return ShareOffline; }
//get the absolute path
pwszCurr = _wfullpath (pwszAbsPath, pwszPath, len + 1);
if (!pwszCurr) { //in order for _wfullpath to fail, something really bad has to happen
//so it is best to return ShareOffline so that we can bail out of
//redirection
return ShareOffline; }
len = wcslen (pwszAbsPath);
if (! ( (2 <= len) && (L'\\' == pwszAbsPath[0]) && (L'\\' == pwszAbsPath[1]) ) ) { //it is a local path if it does not begin with 2 backslashes
return PathLocal; }
//this is a UNC path; so extract the \\server\share part
pwszCurr = wcschr ( & (pwszAbsPath[2]), L'\\');
//first make sure that it is at least of the form \\server\share
//watch out for the \\server\ case
if (!pwszCurr || !pwszCurr[1]) return ShareOffline; //it is an invalid path (no share name)
//the path is of the form \\server\share
//note: the use _wfullpath automatically protects us against the \\server\\ case
pwszCurr = wcschr (&(pwszCurr[1]), L'\\'); if (pwszCurr) //if it is of the form \\server\share\...
*pwszCurr = L'\0';
//now pwszAbsPath is a share name
bRetVal = CSCCheckShareOnline (pwszAbsPath);
if (!bRetVal) { if (ERROR_SUCCESS != GetLastError()) { //either there is really a problem (e.g. invalid share name) or
//it is just a share that is not handled by CSC e.g. a netware share
//or a share with a name that is longer than can be handled by CSC
//so check if the share actually exists
if (0xFFFFFFFF != GetFileAttributes(pwszAbsPath)) { //this can still be a share that is offline since GetFileAttributes
//will return the attributes stored in the cache
Status = 0; bRetVal = GetShareStatus (pwszAbsPath, &Status, &dwPinCount, &dwHints); if (! bRetVal || (! (FLAG_CSC_SHARE_STATUS_DISCONNECTED_OP & Status))) return PathLocal; //this is simply a valid path that CSC cannot handle
else if (bRetVal && (FLAG_CSC_SHARE_STATUS_NO_CACHING == (FLAG_CSC_SHARE_STATUS_CACHING_MASK & Status))) return PathLocal; //CSC caching is not turned on for the share.
} }
//it is indeed an inaccessble share
return ShareOffline; //for all other cases, treat this as offline
} else { //this means that the share is live, but CSC might still think that it
//is offline.
Status = 0; bRetVal = GetShareStatus (pwszAbsPath, &Status, &dwPinCount, &dwHints); if (bRetVal && (FLAG_CSC_SHARE_STATUS_DISCONNECTED_OP & Status)) return ShareOffline; //CSC thinks that the share is offline
else if (bRetVal && (FLAG_CSC_SHARE_STATUS_NO_CACHING == (FLAG_CSC_SHARE_STATUS_CACHING_MASK & Status))) return PathLocal; //CSC caching is not turned on for the share
else if (!bRetVal) return ShareOffline;
//in all other cases, consider the share as online since
//CSCCheckShareOnline has already returned TRUE
return ShareOnline; } }
//+--------------------------------------------------------------------------
//
// Function: GetShareStatus
//
// Synopsis: this function is a wrapper for CSCQueryFileStatus.
// basically CSCQueryFileStatus can fail if there was never a net
// use to a share. So this function tries to create a net use to
// the share if CSCQueryFileStatus fails and then re-queries the
// file status
//
// Arguments: [in] pwszShare : the share name
// [out] pdwStatus : the share Status
// [out] pdwPinCount : the pin count
// [out] pdwHints : the hints
//
// Returns: TRUE : if everything was successful.
// FALSE : if there was an error. In this case, it GetLastError()
// will contain the specific error code.
//
// History: 5/11/1999 RahulTh created
//
// Notes: it is very important that this function be passed a share name
// it does not do any parameter validation. So under no
// circumstance should this function be passed a filename.
//
//---------------------------------------------------------------------------
BOOL GetShareStatus (const WCHAR * pwszShare, DWORD * pdwStatus, DWORD * pdwPinCount, DWORD * pdwHints) { NETRESOURCE nr; DWORD dwResult; DWORD dwErr = NO_ERROR; BOOL bStatus;
bStatus = CSCQueryFileStatus(pwszShare, pdwStatus, pdwPinCount, pdwHints);
if (!bStatus) { //try to connect to the share
ZeroMemory ((PVOID) (&nr), sizeof (NETRESOURCE)); nr.dwType = RESOURCETYPE_DISK; nr.lpLocalName = NULL; nr.lpRemoteName = (LPTSTR) pwszShare; nr.lpProvider = NULL;
dwErr = WNetUseConnection(NULL, &nr, NULL, NULL, 0, NULL, NULL, &dwResult);
if (NO_ERROR == dwErr) { bStatus = CSCQueryFileStatus (pwszShare, pdwStatus, pdwPinCount, pdwHints); if (!bStatus) dwErr = GetLastError(); else dwErr = NO_ERROR;
WNetCancelConnection2 (pwszShare, 0, FALSE); } else { bStatus = FALSE; }
}
SetLastError(dwErr); return bStatus; }
DWORD CmdReconnect( PWSTR ReconnectArg) { DWORD Error = ERROR_SUCCESS; BOOL fRet;
if (fSwDebug == TRUE) MyPrintf(L"CmdReconnect(%ws)\r\n", ReconnectArg);
fRet = CSCTransitionServerOnlineW(ReconnectArg); if (fRet == FALSE) Error = GetLastError();
return Error; }
DWORD CmdQueryFile( PWSTR QueryFileArg) { DWORD HintFlags = 0; DWORD PinCount = 0; DWORD Status = 0; DWORD Error = ERROR_SUCCESS; BOOL fRet;
if (fSwDebug == TRUE) MyPrintf(L"CmdQueryFile(%ws)\r\n", QueryFileArg);
fRet = CSCQueryFileStatusW( QueryFileArg, &Status, &PinCount, &HintFlags);
if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
if (fSwFull != TRUE) { MyPrintf( L"QueryFile of %ws:\r\n" L"Status: 0x%x\r\n" L"PinCount: %d\r\n" L"HintFlags: 0x%x\r\n", QueryFileArg, Status, PinCount, HintFlags); } else { WCHAR StatusBuffer[0x100]; WCHAR HintBuffer[0x100]; if (LooksToBeAShare(QueryFileArg) == TRUE) ShareStatusToEnglish(Status, StatusBuffer); else FileStatusToEnglish(Status, StatusBuffer); HintsToEnglish(HintFlags, HintBuffer); MyPrintf( L"QueryFile of %ws:\r\n" L"Status: 0x%x %ws\r\n" L"PinCount: %d\r\n" L"HintFlags: 0x%x %ws\r\n", QueryFileArg, Status, StatusBuffer, PinCount, HintFlags, HintBuffer); }
AllDone: return Error; }
DWORD CmdQueryFileEx( PWSTR QueryFileExArg) { DWORD HintFlags = 0; DWORD PinCount = 0; DWORD Status = 0; DWORD UserPerms = 0; DWORD OtherPerms = 0; DWORD Error = ERROR_SUCCESS; BOOL fRet; HMODULE hmodCscDll = LoadLibrary(TEXT("cscdll.dll")); CSCQUERYFILESTATUSEXW pCSCQueryFileStatusExW = NULL;
if (fSwDebug == TRUE) MyPrintf(L"CmdQueryFileEx(%ws)\r\n", QueryFileExArg);
if (hmodCscDll == NULL) { Error = GetLastError(); goto AllDone; }
pCSCQueryFileStatusExW = (CSCQUERYFILESTATUSEXW) GetProcAddress( hmodCscDll, "CSCQueryFileStatusExW"); if (pCSCQueryFileStatusExW == NULL) { Error = GetLastError(); goto AllDone; }
fRet = (pCSCQueryFileStatusExW)( QueryFileExArg, &Status, &PinCount, &HintFlags, &UserPerms, &OtherPerms);
if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
if (fSwFull != TRUE) { MyPrintf( L"Query of %ws:\r\n" L"Status: 0x%x\r\n" L"PinCount: %d\r\n" L"HintFlags: 0x%x\r\n" L"UserPerms: 0x%x\r\n" L"OtherPerms: 0x%x\r\n", QueryFileExArg, Status, PinCount, HintFlags, UserPerms, OtherPerms); } else { WCHAR StatusBuffer[0x100] = {0}; WCHAR HintBuffer[0x100] = {0}; if (LooksToBeAShare(QueryFileExArg) == TRUE) ShareStatusToEnglish(Status, StatusBuffer); else FileStatusToEnglish(Status, StatusBuffer); HintsToEnglish(HintFlags, HintBuffer); MyPrintf( L"Query of %ws:\r\n" L"Status: 0x%x %ws\r\n" L"PinCount: %d\r\n" L"HintFlags: 0x%x %ws\r\n" L"UserPerms: 0x%x\r\n" L"OtherPerms: 0x%x\r\n", QueryFileExArg, Status, StatusBuffer, PinCount, HintFlags, HintBuffer, UserPerms, OtherPerms); }
AllDone: if (hmodCscDll != NULL) FreeLibrary(hmodCscDll); return Error; }
DWORD CmdSetSpace( PWSTR SetSpaceArg) { DWORD Error = ERROR_SUCCESS; DWORD MaxSpaceHigh = 0; DWORD MaxSpaceLow; BOOL fRet;
if (fSwDebug == TRUE) MyPrintf(L"CmdSetSpace(%ws)\r\n", SetSpaceArg);
swscanf(SetSpaceArg, L"%d", &MaxSpaceLow);
fRet = CSCSetMaxSpace( MaxSpaceHigh, MaxSpaceLow);
if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
CmdGetSpace();
AllDone: return Error; }
DWORD CmdQueryShare( PWSTR QueryShareArg) { DWORD HintFlags = 0; DWORD PinCount = 0; DWORD Status = 0; DWORD UserPerms = 0; DWORD OtherPerms = 0; DWORD Error = ERROR_SUCCESS; BOOL fRet; HMODULE hmodCscDll = LoadLibrary(TEXT("cscdll.dll")); CSCQUERYSHARESTATUSW pCSCQueryShareStatusW = NULL;
if (fSwDebug == TRUE) MyPrintf(L"CmdQueryShare(%ws)\r\n", QueryShareArg);
if (hmodCscDll == NULL) { Error = GetLastError(); goto AllDone; }
pCSCQueryShareStatusW = (CSCQUERYSHARESTATUSW) GetProcAddress( hmodCscDll, "CSCQueryShareStatusW"); if (pCSCQueryShareStatusW == NULL) { Error = GetLastError(); goto AllDone; }
fRet = (pCSCQueryShareStatusW)( QueryShareArg, &Status, &PinCount, &HintFlags, &UserPerms, &OtherPerms);
if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
if (fSwFull != TRUE) { MyPrintf( L"Query of %ws:\r\n" L"Status: 0x%x\r\n" L"PinCount: %d\r\n" L"HintFlags: 0x%x\r\n" L"UserPerms: 0x%x\r\n" L"OtherPerms: 0x%x\r\n", QueryShareArg, Status, PinCount, HintFlags, UserPerms, OtherPerms); } else { WCHAR StatusBuffer[0x100] = {0}; WCHAR HintBuffer[0x100] = {0}; ShareStatusToEnglish(Status, StatusBuffer); HintsToEnglish(HintFlags, HintBuffer); MyPrintf( L"Query of %ws:\r\n" L"Status: 0x%x %ws\r\n" L"PinCount: %d\r\n" L"HintFlags: 0x%x %ws\r\n" L"UserPerms: 0x%x\r\n" L"OtherPerms: 0x%x\r\n", QueryShareArg, Status, StatusBuffer, PinCount, HintFlags, HintBuffer, UserPerms, OtherPerms); } AllDone: if (hmodCscDll != NULL) FreeLibrary(hmodCscDll); return Error; }
DWORD CmdMerge( PWSTR MergeArg) { DWORD Error = ERROR_SUCCESS; DWORD HowToRespond = CSCPROC_RETURN_CONTINUE; // JMH
BOOL fRet;
if (fSwDebug == TRUE) MyPrintf(L"CmdMerge(%ws)\r\n", MergeArg);
fRet = CSCMergeShareW(MergeArg, MyCscMergeProcW, HowToRespond); if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
fRet = CSCTransitionServerOnlineW(MergeArg); if (fRet == FALSE) Error = GetLastError();
AllDone: return Error; }
DWORD CmdMove( PWSTR MoveArg) {
DWORD Error = ERROR_FILE_NOT_FOUND; LPWSTR lpszTempName = NULL;
if (!CSCCopyReplicaW(MoveArg, &lpszTempName)) { Error = GetLastError(); } else { Error = ERROR_SUCCESS; }
if (Error == ERROR_SUCCESS) MyPrintf(L"Copy is %ws\r\n", lpszTempName);
return Error; }
DWORD CmdEncryptDecrypt( BOOL fEncrypt) { DWORD Error = ERROR_SUCCESS; DWORD EncryptDecryptType = 0; BOOL fRet; HMODULE hmodCscDll = LoadLibrary(TEXT("cscdll.dll")); CSCENCRYPTDECRYPTDATABASE pCSCEncryptDecryptDatabase = NULL;
if (fSwDebug == TRUE) MyPrintf(L"CmdEncryptDecrypt(%ws)\r\n", fEncrypt == TRUE ? L"Encrypt" : L"Decrypt");
if (hmodCscDll == NULL) { Error = GetLastError(); goto AllDone; }
pCSCEncryptDecryptDatabase = (CSCENCRYPTDECRYPTDATABASE) GetProcAddress( hmodCscDll, "CSCEncryptDecryptDatabase"); if (pCSCEncryptDecryptDatabase == NULL) { Error = GetLastError(); goto AllDone; }
fRet = (pCSCEncryptDecryptDatabase)(fEncrypt, MyEncryptDecryptProcW, EncryptDecryptType); if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
AllDone:
if (hmodCscDll != NULL) FreeLibrary(hmodCscDll);
if (fSwDebug == TRUE) MyPrintf(L"CmdEncryptDecrypt exit %d\r\n", Error);
return Error; }
DWORD CmdFill( PWSTR FillArg) { DWORD Error = ERROR_SUCCESS; DWORD HowToRespond = CSCPROC_RETURN_CONTINUE; BOOL fRet;
if (fSwDebug == TRUE) MyPrintf(L"CmdFill(%ws, %d)\r\n", FillArg, fSwFull);
fRet = CSCFillSparseFilesW(FillArg, fSwFull, MyCscFillProcW, HowToRespond); if (fRet == FALSE) { Error = GetLastError(); }
return Error; }
DWORD CmdCheck( PWSTR CheckArg) { DWORD Error = ERROR_SUCCESS; DWORD Speed = 0; BOOL fOnline = FALSE;
if (fSwDebug == TRUE) MyPrintf(L"CmdCheck(%ws)\r\n", CheckArg);
fOnline = CSCCheckShareOnlineExW(CheckArg, &Speed);
MyPrintf( L"%ws is %s\r\n", CheckArg, (fOnline == FALSE) ? L"Offline" : L"Online");
return Error; }
DWORD CmdDBStatus( VOID) { GLOBALSTATUS sGS = {0}; ULONG DBStatus = 0; ULONG DBErrorFlags = 0; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = 0;
if (fSwDebug == TRUE) MyPrintf(L"CmdDBStatus()\r\n");
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdDBStatus:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_GETGLOBALSTATUS, // control code
(LPVOID)&sGS, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (!bResult) { MyPrintf(L"CmdDBStatus:DeviceIoControl IOCTL_GETGLOBALSTATUS failed\n"); Status = GetLastError(); goto AllDone; }
DBStatus = sGS.sST.uFlags; DBErrorFlags = sGS.uDatabaseErrorFlags;
if (DBStatus & FLAG_DATABASESTATUS_DIRTY) MyPrintf(L"FLAG_DATABASESTATUS_DIRTY\r\n"); if (DBStatus & FLAG_DATABASESTATUS_UNENCRYPTED) MyPrintf(L"FLAG_DATABASESTATUS_UNENCRYPTED\r\n"); if (DBStatus & FLAG_DATABASESTATUS_PARTIALLY_UNENCRYPTED) MyPrintf(L"FLAG_DATABASESTATUS_PARTIALLY_UNENCRYPTED\r\n"); if (DBStatus & FLAG_DATABASESTATUS_ENCRYPTED) MyPrintf(L"FLAG_DATABASESTATUS_ENCRYPTED\r\n"); if (DBStatus & FLAG_DATABASESTATUS_PARTIALLY_ENCRYPTED) MyPrintf(L"FLAG_DATABASESTATUS_PARTIALLY_ENCRYPTED\r\n"); MyPrintf(L"Database Error Flags : 0x%x\r\n", DBErrorFlags);
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdDBStatus exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
DWORD CmdPurge( PWSTR PurgeArg) { ULONG nFiles = 0; ULONG nYoungFiles = 0; ULONG Status = ERROR_SUCCESS; ULONG Timeout = 120; BOOL fRet = FALSE; HMODULE hmodCscDll = LoadLibrary(TEXT("cscdll.dll")); CSCPURGEUNPINNEDFILES pCSCPurgeUnpinnedFiles = NULL;
if (fSwDebug == TRUE) MyPrintf(L"CmdPurge(%ws)\r\n", PurgeArg);
if (hmodCscDll == NULL) { Status = GetLastError(); goto AllDone; }
pCSCPurgeUnpinnedFiles = (CSCPURGEUNPINNEDFILES) GetProcAddress( hmodCscDll, "CSCPurgeUnpinnedFiles"); if (pCSCPurgeUnpinnedFiles == NULL) { Status = GetLastError(); goto AllDone; }
if (PurgeArg != NULL) swscanf(PurgeArg, L"%d", &Timeout);
if (fSwDebug == TRUE) MyPrintf(L"Timeout=%d seconds\r\n", Timeout);
fRet = (pCSCPurgeUnpinnedFiles)(Timeout, &nFiles, &nYoungFiles); if (fRet == FALSE) { Status = GetLastError(); goto AllDone; } MyPrintf(L"nFiles = %d nYoungFiles=%d\n", nFiles, nYoungFiles);
AllDone: if (hmodCscDll != NULL) FreeLibrary(hmodCscDll); if (fSwDebug == TRUE) MyPrintf(L"CmdPurge exit %d\r\n", Status);
return Status; }
DWORD CmdPQEnum( VOID) { PQPARAMS PQP = {0}; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = 0;
if (fSwDebug == TRUE) MyPrintf(L"CmdPQEnum()\r\n");
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdPQEnum:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
MyPrintf(L" POS SHARE DIR SHADOW STATUS REFPRI HPRI HINTFLG HINTPRI VER\r\n");
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_SHADOW_BEGIN_PQ_ENUM, // control code
(LPVOID)&PQP, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (!bResult) { MyPrintf(L"CmdPQEnum:DeviceIoControl IOCTL_SHADOW_BEGIN_PQ_ENUM failed\n"); Status = GetLastError(); goto AllDone; }
do { bResult = DeviceIoControl( hDBShadow, // device
IOCTL_SHADOW_NEXT_PRI_SHADOW, // control code
(LPVOID)&PQP, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (bResult) { MyPrintf(L"%5d %5x %8x %8x %8x %6d %6x %7d %7d %4d\r\n", PQP.uPos, PQP.hShare, PQP.hDir, PQP.hShadow, PQP.ulStatus, PQP.ulRefPri, PQP.ulIHPri, PQP.ulHintFlags, PQP.ulHintPri, PQP.dwPQVersion); } } while (bResult && PQP.uPos != 0);
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_SHADOW_END_PQ_ENUM, // control code
(LPVOID)&PQP, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdPQEnum exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
LPWSTR ConvertGmtTimeToString( FILETIME Time, LPWSTR OutputBuffer) { FILETIME LocalTime; SYSTEMTIME SystemTime;
static FILETIME ftNone = {0, 0};
if (memcmp(&Time, &ftNone, sizeof(FILETIME)) == 0) { wsprintf (OutputBuffer, L"<none>"); } else { FileTimeToLocalFileTime( &Time , &LocalTime ); FileTimeToSystemTime( &LocalTime, &SystemTime ); wsprintf( OutputBuffer, L"%02u/%02u/%04u %02u:%02u:%02u ", SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond ); } return( OutputBuffer ); }
VOID DumpCscEntryInfo( LPWSTR Path, PWIN32_FIND_DATA Find32, DWORD Status, DWORD PinCount, DWORD HintFlags, PFILETIME OrgTime) { WCHAR TimeBuf1[40]; WCHAR TimeBuf2[40]; FILE *fp = NULL;
if (fSwTouch == TRUE) { if (Path == NULL) { wsprintf(NameBuf, L"%ws", Find32->cFileName); } else { wsprintf(NameBuf, L"%ws\\%ws", Path, Find32->cFileName); } MyPrintf(L"%ws\r\n", NameBuf); if ((Find32->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { fp = _wfopen(NameBuf, L"rb"); if (fp != NULL) fclose(fp); } } else if (fSwFull == TRUE) { WCHAR StatusBuffer[0x100]; WCHAR HintBuffer[0x100];
if (Path != NULL) MyPrintf(L"Directory %ws\r\n", Path); ConvertGmtTimeToString(Find32->ftLastWriteTime, TimeBuf1); MyPrintf( L"LFN: %s\r\n" L"SFN: %s\r\n" L"Attr: 0x%x\r\n" L"Size: 0x%x:0x%x\r\n" L"LastWriteTime: %ws\r\n", Find32->cFileName, Find32->cAlternateFileName, Find32->dwFileAttributes, Find32->nFileSizeHigh, Find32->nFileSizeLow, TimeBuf1);
if (OrgTime) { ConvertGmtTimeToString(*OrgTime, TimeBuf1); MyPrintf(L"ORGTime: %ws\r\n", TimeBuf1); } StatusBuffer[0] = L'\0'; HintBuffer[0] = L'\0'; if (Path == NULL) { ShareStatusToEnglish(Status, StatusBuffer); HintsToEnglish(HintFlags, HintBuffer); } else { if (LooksToBeAShare(Path) == TRUE) ShareStatusToEnglish(Status, StatusBuffer); else FileStatusToEnglish(Status, StatusBuffer); HintsToEnglish(HintFlags, HintBuffer); } MyPrintf( L"Status: 0x%x %ws\r\n" L"PinCount: %d\r\n" L"HintFlags: 0x%x %ws\r\n\r\n", Status, StatusBuffer, PinCount, HintFlags, HintBuffer); } else { if (Path == NULL) { MyPrintf(L"%ws\r\n", Find32->cFileName); } else { MyPrintf(L"%ws\\%ws\r\n", Path, Find32->cFileName); } MyPrintf(L" Attr=0x%x Size=0x%x:0x%x Status=0x%x PinCount=%d HintFlags=0x%x\r\n", Find32->dwFileAttributes, Find32->nFileSizeHigh, Find32->nFileSizeLow, Status, PinCount, HintFlags); ConvertGmtTimeToString(Find32->ftLastWriteTime, TimeBuf1); if (OrgTime) ConvertGmtTimeToString(*OrgTime, TimeBuf2); else wcscpy(TimeBuf2, L"<none>"); MyPrintf(L" LastWriteTime: %ws OrgTime: %ws\r\n", TimeBuf1, TimeBuf2); MyPrintf(L"\r\n"); } }
DWORD CmdEnum( PWSTR EnumArg) { HANDLE hFind; DWORD Error = ERROR_SUCCESS; DWORD Status = 0; DWORD PinCount = 0; DWORD HintFlags = 0; FILETIME ftOrgTime = {0}; WIN32_FIND_DATAW sFind32 = {0}; WCHAR FullPath[MAX_PATH];
if (fSwDebug == TRUE) MyPrintf(L"CmdEnum(%ws)\r\n", EnumArg);
hFind = CSCFindFirstFileW(EnumArg, &sFind32, &Status, &PinCount, &HintFlags, &ftOrgTime); if (hFind == INVALID_HANDLE_VALUE) { Error = GetLastError(); goto AllDone; } DumpCscEntryInfo(EnumArg, &sFind32, Status, PinCount, HintFlags, &ftOrgTime); if (fSwRecurse == TRUE && (sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (EnumArg != NULL) { wcscpy(FullPath, EnumArg); wcscat(FullPath, L"\\"); } else { wcscpy(FullPath, L""); } wcscat(FullPath, sFind32.cFileName); CmdEnum(FullPath); } while (CSCFindNextFileW(hFind, &sFind32, &Status, &PinCount, &HintFlags, &ftOrgTime)) { DumpCscEntryInfo(EnumArg, &sFind32, Status, PinCount, HintFlags, &ftOrgTime); if (fSwRecurse == TRUE && (sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { if (EnumArg != NULL) { wcscpy(FullPath, EnumArg); wcscat(FullPath, L"\\"); } else { wcscpy(FullPath, L""); } wcscat(FullPath, sFind32.cFileName); CmdEnum(FullPath); } } CSCFindClose(hFind);
AllDone: return (Error); }
DWORD CmdEnumForStats( PWSTR EnumForStatsArg) { DWORD Error = ERROR_SUCCESS; DWORD EnumForStatsType = 0; BOOL fRet;
if (fSwDebug == TRUE) MyPrintf(L"CmdEnumForStats()\r\n");
fRet = CSCEnumForStatsW(EnumForStatsArg, MyEnumForStatsProcW, EnumForStatsType); if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdEnumForStats exit %d\r\n", Error);
return Error; }
DWORD CmdDelete( PWSTR DeleteArg) { DWORD Error = ERROR_SUCCESS; DWORD Status = 0; DWORD PinCount = 0; DWORD HintFlags = 0; FILETIME ftOrgTime = {0}; BOOL fResult; HANDLE hFind; WIN32_FIND_DATAW sFind32 = {0}; WCHAR FullPath[MAX_PATH];
if (fSwDebug == TRUE) MyPrintf(L"CmdDelete(%ws)\r\n", DeleteArg);
//
// Non-recursive delete
//
if (fSwRecurse == FALSE) { fResult = CSCDeleteW(DeleteArg); if (fResult == FALSE) Error = GetLastError(); goto AllDone; } //
// Delete recursively, using eumeration
//
hFind = CSCFindFirstFileW(DeleteArg, &sFind32, &Status, &PinCount, &HintFlags, &ftOrgTime); if (hFind == INVALID_HANDLE_VALUE) { Error = GetLastError(); goto AllDone; } if (DeleteArg != NULL) { wcscpy(FullPath, DeleteArg); wcscat(FullPath, L"\\"); } else { wcscpy(FullPath, L""); } wcscat(FullPath, sFind32.cFileName); if (sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) CmdDelete(FullPath); MyPrintf(L"CSCDeleteW(%ws) -> %d\r\n", FullPath, CSCDeleteW(FullPath)); while (CSCFindNextFileW(hFind, &sFind32, &Status, &PinCount, &HintFlags, &ftOrgTime)) { if (DeleteArg != NULL) { wcscpy(FullPath, DeleteArg); wcscat(FullPath, L"\\"); } else { wcscpy(FullPath, L""); } wcscat(FullPath, sFind32.cFileName); if (sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) CmdDelete(FullPath); MyPrintf(L"CSCDeleteW(%ws) -> %d\r\n", FullPath, CSCDeleteW(FullPath)); } CSCFindClose(hFind);
AllDone: return (Error); }
DWORD CmdDeleteShadow( PWSTR DeleteShadowArg) { HSHADOW hDir; HSHADOW hShadow; SHADOWINFO sSI; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = 0; ULONG hShare;
if (fSwDebug == TRUE) MyPrintf(L"CmdDeleteShadow(%ws)\r\n", DeleteShadowArg);
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdDeleteShadow:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
swscanf(DeleteShadowArg, L"0x%x:0x%x", &hDir, &hShadow);
if (fSwDebug == TRUE) MyPrintf(L"CmdDeleteShadow: hDir:0x%x hShadow:0x%x\r\n", hDir, hShadow);
memset(&sSI, 0, sizeof(SHADOWINFO)); sSI.hDir = hDir; sSI.hShadow = hShadow;
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_SHADOW_DELETE, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (!bResult) { MyPrintf( L"CmdDeleteShadow:DeviceIoControl IOCTL_SHADOW_DELETE failed 0x%x\n", sSI.dwError); Status = sSI.dwError; goto AllDone; }
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdDeleteShadow exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
DWORD CmdPinUnPin( BOOL fPin, PWSTR PinArg) { BOOL fRet; HANDLE hFind; DWORD Error = ERROR_SUCCESS; DWORD Status = 0; DWORD PinCount = 0; DWORD HintFlags = 0; FILETIME ftOrgTime = {0}; WIN32_FIND_DATAW sFind32 = {0}; WCHAR FullPath[MAX_PATH];
if (fSwDebug == TRUE) MyPrintf(L"CmdPinUnPin(%d,%ws)\r\n", fPin, PinArg);
if (fSwUser == TRUE && fSwSystem == TRUE) { MyPrintf(L"Can not use both /SYSTEM and /USER\r\n"); goto AllDone; }
if (fSwUser == TRUE) { if (fSwInherit == TRUE) HintFlags |= FLAG_CSC_HINT_PIN_INHERIT_USER; else HintFlags |= FLAG_CSC_HINT_PIN_USER; } if (fSwSystem == TRUE) { if (fSwInherit == TRUE) HintFlags |= FLAG_CSC_HINT_PIN_INHERIT_SYSTEM; else HintFlags |= FLAG_CSC_HINT_PIN_SYSTEM; }
if (fSwRecurse == TRUE && fPin == TRUE) { MyPrintf(L"Can not pin recursively.\r\n"); goto AllDone; } //
// Pin/Unpin one file
//
if (fSwRecurse == FALSE) { if (fPin == TRUE) { fRet = CSCPinFileW(PinArg, HintFlags, &Status, &PinCount, &HintFlags); } else { fRet = CSCUnpinFileW(PinArg, HintFlags, &Status, &PinCount, &HintFlags); }
if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
MyPrintf( L"%ws of %ws:\r\n" L"Status: 0x%x\r\n" L"PinCount: %d\r\n" L"HintFlags: 0x%x\r\n", fPin ? L"Pin" : L"Unpin", PinArg, Status, PinCount, HintFlags);
goto AllDone; } //
// Unpin recursively, using eumeration
//
hFind = CSCFindFirstFileW(PinArg, &sFind32, &Status, &PinCount, &HintFlags, &ftOrgTime); if (hFind == INVALID_HANDLE_VALUE) { Error = GetLastError(); goto AllDone; } if (PinArg != NULL) { wcscpy(FullPath, PinArg); wcscat(FullPath, L"\\"); } else { wcscpy(FullPath, L""); } wcscat(FullPath, sFind32.cFileName); if (sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) CmdPinUnPin(fPin, FullPath); fRet = CSCUnpinFileW(FullPath, HintFlags, &Status, &PinCount, &HintFlags); MyPrintf(L"CSCUnpinFile(%ws) -> %d\r\n", FullPath, fRet); while (CSCFindNextFileW(hFind, &sFind32, &Status, &PinCount, &HintFlags, &ftOrgTime)) { if (PinArg != NULL) { wcscpy(FullPath, PinArg); wcscat(FullPath, L"\\"); } else { wcscpy(FullPath, L""); } wcscat(FullPath, sFind32.cFileName); if (sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) CmdPinUnPin(fPin, FullPath); fRet = CSCUnpinFileW(FullPath, HintFlags, &Status, &PinCount, &HintFlags); MyPrintf(L"CSCUnpinFile(%ws) -> %d\r\n", FullPath, fRet); } CSCFindClose(hFind); AllDone:
return Error; }
DWORD MyCscMergeProcW( LPCWSTR lpszFullPath, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *lpFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext) { if (dwReason == CSCPROC_REASON_BEGIN || dwReason == CSCPROC_REASON_MORE_DATA) { if (dwReason == CSCPROC_REASON_BEGIN) { MyPrintf( L"BEGIN[%ws][%d/%d]", (lpszFullPath) ? lpszFullPath : L"None", dwParam1, dwParam2); } else if (dwReason == CSCPROC_REASON_MORE_DATA) { MyPrintf( L"MORE_DATA[%ws][%d/%d]", (lpszFullPath) ? lpszFullPath : L"None", dwParam1, dwParam2); } if (fSwAbort) { MyPrintf(L":Abort\r\n"); return CSCPROC_RETURN_ABORT; } else if (fSwSkip) { MyPrintf(L":Skip\r\n"); return CSCPROC_RETURN_SKIP; } else if (fSwRetry) { MyPrintf(L"Retry\r\n"); return CSCPROC_RETURN_RETRY; } else if (fSwAsk) { MyPrintf(L" - (R)etry/(A)bort/(S)kip/(C)ontinue:"); return CscMergeFillAsk(lpszFullPath); } else { MyPrintf(L"Continue\r\n"); return (DWORD)dwContext; } }
MyPrintf( L"END[%ws]:", (lpszFullPath) ? lpszFullPath : L"None"); if (dwParam2 == ERROR_SUCCESS) { MyPrintf(L"SUCCEEDED\r\n"); } else { MyPrintf(L"ERROR=%d \r\n", dwParam2); } return (DWORD)dwContext; }
DWORD MyCscFillProcW( LPCWSTR lpszFullPath, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *lpFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext) { if (dwReason == CSCPROC_REASON_BEGIN || dwReason == CSCPROC_REASON_MORE_DATA) { if (dwReason == CSCPROC_REASON_BEGIN) { MyPrintf( L"BEGIN[%ws][%d/%d]", (lpszFullPath) ? lpszFullPath : L"None", dwParam1, dwParam2); } else if (dwReason == CSCPROC_REASON_MORE_DATA) { MyPrintf( L"MORE_DATA[%ws][%d/%d]", (lpszFullPath) ? lpszFullPath : L"None", dwParam1, dwParam2); } if (fSwAbort) { MyPrintf(L":Abort\r\n"); return CSCPROC_RETURN_ABORT; } else if (fSwSkip) { MyPrintf(L":Skip\r\n"); return CSCPROC_RETURN_SKIP; } else if (fSwRetry) { MyPrintf(L"Retry\r\n"); return CSCPROC_RETURN_RETRY; } else if (fSwAsk) { MyPrintf(L" - (R)etry/(A)bort/(S)kip/(C)ontinue:"); return CscMergeFillAsk(lpszFullPath); } else { MyPrintf(L"Continue\r\n"); return (DWORD)dwContext; } }
MyPrintf( L"END[%ws]:", (lpszFullPath) ? lpszFullPath : L"None"); if (dwParam2 == ERROR_SUCCESS) { MyPrintf(L"SUCCEEDED\r\n"); } else { MyPrintf(L"ERROR=%d \r\n", dwParam2); } return (DWORD)dwContext; }
DWORD CscMergeFillAsk(LPCWSTR lpszFullPath) { WCHAR wch; ULONG ulid; LONG cnt; WCHAR rgwch[256]; PWCHAR lpBuff = NULL;
do { lpBuff = rgwch; memset(rgwch, 0, sizeof(rgwch)); if (!fgetws(rgwch, sizeof(rgwch)/sizeof(WCHAR), stdin)) break; // Chop leading blanks
if (lpBuff != NULL) while (*lpBuff != L'\0' && *lpBuff == L' ') lpBuff++;
cnt = swscanf(lpBuff, L"%c", &wch);
if (!cnt) continue;
switch (wch) { case L's': case L'S': return CSCPROC_RETURN_SKIP; case L'c': case L'C': return CSCPROC_RETURN_CONTINUE; case L'a': case L'A': return CSCPROC_RETURN_ABORT; case L'r': case L'R': return CSCPROC_RETURN_RETRY; } } while (1);
return CSCPROC_RETURN_CONTINUE; }
DWORD MyEncryptDecryptProcW( LPCWSTR lpszFullPath, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *lpFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext) { if (dwReason == CSCPROC_REASON_BEGIN) { return CSCPROC_RETURN_CONTINUE; } else if (dwReason == CSCPROC_REASON_MORE_DATA) { MyPrintf(L"%ws\r\n", (lpszFullPath != NULL) ? lpszFullPath : L"None"); return CSCPROC_RETURN_CONTINUE; } //
// CSC_PROC_END
//
if (dwParam2 == ERROR_SUCCESS) { MyPrintf(L"Succeeded\r\n"); } else { MyPrintf(L"Error=%d \r\n", dwParam2); } return CSCPROC_RETURN_CONTINUE; }
DWORD MyEnumForStatsProcW( LPCWSTR lpszFullPath, DWORD dwStatus, DWORD dwHintFlags, DWORD dwPinCount, WIN32_FIND_DATAW *lpFind32, DWORD dwReason, DWORD dwParam1, DWORD dwParam2, DWORD_PTR dwContext) { if (dwReason == CSCPROC_REASON_BEGIN) { MyPrintf(L"(1)%ws ", (lpszFullPath != NULL) ? lpszFullPath : L"None"); if (lpFind32 != NULL) MyPrintf(L"[%ws]\r\n", lpFind32->cFileName); MyPrintf(L" Status=0x%02x HintFlags=0x%02x " L"Pincount=%3d Reason=0x%x Param1=0x%x Param2=0x%x\r\n", dwStatus, dwHintFlags, dwPinCount, dwReason, dwParam1, dwParam2); return CSCPROC_RETURN_CONTINUE; } else if (dwReason == CSCPROC_REASON_MORE_DATA) { MyPrintf(L"(2)%ws ", (lpszFullPath != NULL) ? lpszFullPath : L"None"); if (lpFind32 != NULL) MyPrintf(L" %ws\r\n", lpFind32->cFileName); MyPrintf(L" Status=0x%02x HintFlags=0x%02x " L"Pincount=%3d Reason=0x%x Param1=0x%x Param2=0x%x\r\n", dwStatus, dwHintFlags, dwPinCount, dwReason, dwParam1, dwParam2); return CSCPROC_RETURN_CONTINUE; } //
// CSC_PROC_END
//
MyPrintf(L"(3)%ws\r\n", (lpszFullPath != NULL) ? lpszFullPath : L"None"); if (dwParam2 == ERROR_SUCCESS) { MyPrintf(L"Succeeded\r\n"); } else { MyPrintf(L"Error=%d \r\n", dwParam2); } return CSCPROC_RETURN_CONTINUE; }
struct { DWORD ShareStatus; LPWSTR ShareStatusName; } ShareStatusStuff[] = { { FLAG_CSC_SHARE_STATUS_MODIFIED_OFFLINE, L"MODIFIED_OFFLINE " }, { FLAG_CSC_SHARE_STATUS_CONNECTED, L"CONNECTED " }, { FLAG_CSC_SHARE_STATUS_FILES_OPEN, L"FILES_OPEN " }, { FLAG_CSC_SHARE_STATUS_FINDS_IN_PROGRESS, L"FINDS_IN_PROGRESS " }, { FLAG_CSC_SHARE_STATUS_DISCONNECTED_OP, L"DISCONNECTED_OP " }, { FLAG_CSC_SHARE_MERGING, L"MERGING " }, { 0, NULL } };
DWORD ShareStatusToEnglish( DWORD Status, LPWSTR OutputBuffer) { ULONG i;
OutputBuffer[0] = L'\0'; for (i = 0; ShareStatusStuff[i].ShareStatusName; i++) { if (Status & ShareStatusStuff[i].ShareStatus) wcscat(OutputBuffer, ShareStatusStuff[i].ShareStatusName); } if ((Status & FLAG_CSC_SHARE_STATUS_CACHING_MASK) == FLAG_CSC_SHARE_STATUS_MANUAL_REINT) wcscat(OutputBuffer, L"MANUAL_REINT "); else if ((Status & FLAG_CSC_SHARE_STATUS_CACHING_MASK) == FLAG_CSC_SHARE_STATUS_AUTO_REINT) wcscat(OutputBuffer, L"AUTO_REINT "); else if ((Status & FLAG_CSC_SHARE_STATUS_CACHING_MASK) == FLAG_CSC_SHARE_STATUS_VDO) wcscat(OutputBuffer, L"VDO "); else if ((Status & FLAG_CSC_SHARE_STATUS_CACHING_MASK) == FLAG_CSC_SHARE_STATUS_NO_CACHING) wcscat(OutputBuffer, L"NO_CACHING "); return 0; }
struct { DWORD FileStatus; LPWSTR FileStatusName; } FileStatusStuff[] = { { FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED, L"DATA_LOCALLY_MODIFIED " }, { FLAG_CSC_COPY_STATUS_ATTRIB_LOCALLY_MODIFIED, L"ATTRIB_LOCALLY_MODIFIED " }, { FLAG_CSC_COPY_STATUS_TIME_LOCALLY_MODIFIED, L"TIME_LOCALLY_MODIFIED " }, { FLAG_CSC_COPY_STATUS_STALE, L"STALE " }, { FLAG_CSC_COPY_STATUS_LOCALLY_DELETED, L"LOCALLY_DELETED " }, { FLAG_CSC_COPY_STATUS_SPARSE, L"SPARSE " }, { FLAG_CSC_COPY_STATUS_ORPHAN, L"ORPHAN " }, { FLAG_CSC_COPY_STATUS_SUSPECT, L"SUSPECT " }, { FLAG_CSC_COPY_STATUS_LOCALLY_CREATED, L"LOCALLY_CREATED " }, { 0x00010000, L"USER_READ " }, { 0x00020000, L"USER_WRITE " }, { 0x00040000, L"GUEST_READ " }, { 0x00080000, L"GUEST_WRITE " }, { 0x00100000, L"OTHER_READ " }, { 0x00200000, L"OTHER_WRITE " }, { FLAG_CSC_COPY_STATUS_IS_FILE, L"IS_FILE " }, { FLAG_CSC_COPY_STATUS_FILE_IN_USE, L"FILE_IN_USE " }, { 0, NULL } };
DWORD FileStatusToEnglish( DWORD Status, LPWSTR OutputBuffer) { ULONG i;
OutputBuffer[0] = L'\0'; for (i = 0; FileStatusStuff[i].FileStatusName; i++) { if (Status & FileStatusStuff[i].FileStatus) wcscat(OutputBuffer, FileStatusStuff[i].FileStatusName); } return 0; }
struct { DWORD HintFlag; LPWSTR HintName; } HintStuff[] = { { FLAG_CSC_HINT_PIN_USER, L"PIN_USER " }, { FLAG_CSC_HINT_PIN_INHERIT_USER, L"PIN_INHERIT_USER " }, { FLAG_CSC_HINT_PIN_INHERIT_SYSTEM, L"PIN_INHERIT_SYSTEM " }, { FLAG_CSC_HINT_CONSERVE_BANDWIDTH, L"CONSERVE_BANDWIDTH " }, { FLAG_CSC_HINT_PIN_SYSTEM, L"PIN_SYSTEM " }, { 0, NULL } };
DWORD HintsToEnglish( DWORD Hint, LPWSTR OutputBuffer) { ULONG i;
OutputBuffer[0] = L'\0'; for (i = 0; HintStuff[i].HintName; i++) { if (Hint & HintStuff[i].HintFlag) wcscat(OutputBuffer, HintStuff[i].HintName); } return 0; }
BOOLEAN LooksToBeAShare(LPWSTR Name) { //
// See if we have \\server\share or \\server\share\<something>
// Assume a valid name passed in...
//
ULONG Len = wcslen(Name); ULONG i; ULONG SlashCount = 0;
// Remove any trailing '\'s
while (Len >= 1) { if (Name[Len-1] == L'\\') { Name[Len-1] = L'\0'; Len--; } else { break; } } for (i = 0; Name[i]; i++) { if (Name[i] == L'\\') SlashCount++; } if (SlashCount > 3) return FALSE;
return TRUE; }
DWORD CmdDisconnect( PWSTR DisconnectArg) { HSHADOW hDir; SHADOWINFO sSI; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = 0; ULONG hShare; PWCHAR wCp; ULONG SlashCount = 0;
if (fSwDebug == TRUE) MyPrintf(L"CmdDisconnect(%ws)\r\n", DisconnectArg);
GetFileAttributes(DisconnectArg);
Status = GetLastError(); if (Status != NO_ERROR) goto AllDone;
SlashCount = 0; for (wCp = DisconnectArg; *wCp; wCp++) { if (*wCp == L'\\') SlashCount++; if (SlashCount == 3) { *wCp = L'\0'; break; } }
hDBShadow = CreateFile( L"\\\\.\\shadow", FILE_EXECUTE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdDisconnect:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
memset(&sSI, 0, sizeof(SHADOWINFO)); sSI.cbBufferSize = (wcslen(DisconnectArg)+1) * sizeof(WCHAR); sSI.lpBuffer = DisconnectArg;
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_TAKE_SERVER_OFFLINE, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (!bResult) { MyPrintf(L"CmdDisconnect:DeviceIoControl IOCTL_TAKE_SERVER_OFFLINE failed\n"); Status = GetLastError(); goto AllDone; }
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdDisconnect exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
DWORD CmdGetShadow( PWSTR GetShadowArg) { DWORD Status = 0; DWORD dwErr = ERROR_SUCCESS; HANDLE hDBShadow = INVALID_HANDLE_VALUE; HSHADOW hShadow = 0; HSHADOW hDir = 0; WIN32_FIND_DATAW sFind32 = {0}; SHADOWINFO sSI = {0}; PWCHAR wCp = NULL; BOOL bResult = FALSE; DWORD junk; WCHAR TimeBuf1[40]; WCHAR TimeBuf2[40]; WCHAR TimeBuf3[40];
if (fSwDebug == TRUE) MyPrintf(L"CmdGetShadow(%ws)\r\n", GetShadowArg);
if (GetShadowArg == NULL) { dwErr = ERROR_INVALID_PARAMETER; goto AllDone; }
swscanf(GetShadowArg, L"%x:", &hDir); for (wCp = GetShadowArg; *wCp && *wCp != L':'; wCp++) ; if (*wCp != L':') { dwErr = ERROR_INVALID_PARAMETER; goto AllDone; } wCp++; if (wcslen(wCp) >= MAX_PATH) { dwErr = ERROR_INVALID_PARAMETER; goto AllDone; } wcscpy(sFind32.cFileName, wCp);
if (fSwDebug == TRUE) MyPrintf(L"hDir=0x%x cFileName=[%ws]\r\n", hDir, sFind32.cFileName);
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdGetShadow:Failed open of shadow device\r\n"); dwErr = GetLastError(); goto AllDone; }
sSI.hDir = hDir; sSI.lpFind32 = &sFind32;
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_GETSHADOW, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (!bResult) { MyPrintf(L"CmdGetShadow:DeviceIoControl IOCTL_GETSHADOW failed\n"); dwErr = GetLastError(); goto AllDone; }
ConvertGmtTimeToString(sFind32.ftCreationTime, TimeBuf1); ConvertGmtTimeToString(sFind32.ftLastAccessTime, TimeBuf2); ConvertGmtTimeToString(sFind32.ftLastWriteTime, TimeBuf3);
MyPrintf(L"\r\n"); MyPrintf(L"%ws:\r\n" L" Size=0x%x:0x%x Attr=0x%x\r\n" L" CreationTime: %ws\r\n" L" LastAccessTime: %ws\r\n" L" LastWriteTime: %ws\r\n", sFind32.cFileName, sFind32.nFileSizeHigh, sFind32.nFileSizeLow, sFind32.dwFileAttributes, TimeBuf1, TimeBuf2, TimeBuf3); MyPrintf(L" hShare=0x%x hDir=0x%x hShadow=0x%x Status=0x%x HintFlags=0x%x\r\n", sSI.hShare, sSI.hDir, sSI.hShadow, sSI.uStatus, sSI.ulHintFlags); MyPrintf(L"\r\n");
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdGetShadowArg exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return dwErr; }
DWORD CmdGetShadowInfo( PWSTR GetShadowInfoArg) { DWORD Status = 0; DWORD dwErr = ERROR_SUCCESS; HANDLE hDBShadow = INVALID_HANDLE_VALUE; HSHADOW hShadow = 0; HSHADOW hDir = 0; WIN32_FIND_DATAW sFind32 = {0}; SHADOWINFO sSI = {0}; BOOL bResult = FALSE; DWORD junk; WCHAR TimeBuf1[40]; WCHAR TimeBuf2[40]; WCHAR TimeBuf3[40];
if (fSwDebug == TRUE) MyPrintf(L"CmdGetShadowInfo(%ws)\r\n", GetShadowInfoArg);
if (GetShadowInfoArg == NULL) { dwErr = ERROR_INVALID_PARAMETER; goto AllDone; }
swscanf(GetShadowInfoArg, L"%x:%x", &hDir, &hShadow);
if (fSwDebug == TRUE) MyPrintf(L"hDir=0x%x hShadow=0x%x\r\n", hDir, hShadow);
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdGetShadowInfo:Failed open of shadow device\r\n"); dwErr = GetLastError(); goto AllDone; }
sSI.hDir = hDir; sSI.hShadow = hShadow; sSI.lpFind32 = &sFind32;
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_SHADOW_GET_SHADOW_INFO, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (!bResult) { MyPrintf(L"CmdGetShadowInfo:DeviceIoControl IOCTL_SHADOW_GET_SHADOW_INFO failed\n"); dwErr = GetLastError(); goto AllDone; }
ConvertGmtTimeToString(sFind32.ftCreationTime, TimeBuf1); ConvertGmtTimeToString(sFind32.ftLastAccessTime, TimeBuf2); ConvertGmtTimeToString(sFind32.ftLastWriteTime, TimeBuf3);
MyPrintf(L"\r\n"); MyPrintf(L"%ws:\r\n" L" Size=0x%x:0x%x Attr=0x%x\r\n" L" CreationTime: %ws\r\n" L" LastAccessTime: %ws\r\n" L" LastWriteTime: %ws\r\n", sFind32.cFileName, sFind32.nFileSizeHigh, sFind32.nFileSizeLow, sFind32.dwFileAttributes, TimeBuf1, TimeBuf2, TimeBuf3); MyPrintf(L"\r\n");
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdGetShadowInfoArg exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return dwErr; }
DWORD CmdShareId( PWSTR ShareIdArg) { DWORD dwErr = ERROR_SUCCESS; ULONG ShareId = 0; BOOL fRet; WCHAR Buffer[100]; ULONG BufSize = sizeof(Buffer); HMODULE hmodCscDll = LoadLibrary(TEXT("cscdll.dll")); CSCSHAREIDTOSHARENAME pCSCShareIdToShareName = NULL;
if (fSwDebug == TRUE) MyPrintf(L"CmdShareId(%ws)\r\n", ShareIdArg);
if (ShareIdArg == NULL) { dwErr = ERROR_INVALID_PARAMETER; goto AllDone; }
swscanf(ShareIdArg, L"%x", &ShareId);
if (fSwDebug == TRUE) MyPrintf(L"ShareId=0x%x\r\n", ShareId);
if (hmodCscDll == NULL) { dwErr = GetLastError(); goto AllDone; }
pCSCShareIdToShareName = (CSCSHAREIDTOSHARENAME) GetProcAddress( hmodCscDll, "CSCShareIdToShareName"); if (pCSCShareIdToShareName == NULL) { dwErr = GetLastError(); goto AllDone; }
fRet = (pCSCShareIdToShareName)(ShareId, (PBYTE)Buffer, &BufSize); if (fRet == FALSE) { dwErr = GetLastError(); goto AllDone; }
MyPrintf(L"ShareId 0x%x = %ws\r\n", ShareId, Buffer);
AllDone:
if (hmodCscDll != NULL) FreeLibrary(hmodCscDll);
if (fSwDebug == TRUE) MyPrintf(L"CmdShareIdToShareName exit %d\r\n", dwErr);
return dwErr; }
DWORD CmdExclusionList( PWSTR ExclusionListArg) { HSHADOW hDir; SHADOWINFO sSI; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = 0; ULONG hShare;
if (fSwDebug == TRUE) MyPrintf(L"CmdExclusionList(%ws)\r\n", ExclusionListArg);
if (ExclusionListArg == NULL) { ExclusionListArg = vtzDefaultExclusionList; } MyPrintf(L"Setting exclusion list to \"%ws\"\r\n", ExclusionListArg);
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdExclusionList:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
memset(&sSI, 0, sizeof(SHADOWINFO)); sSI.uSubOperation = SHADOW_SET_EXCLUSION_LIST; sSI.lpBuffer = ExclusionListArg; sSI.cbBufferSize = (wcslen(ExclusionListArg)+1) * sizeof(WCHAR);
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_DO_SHADOW_MAINTENANCE, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdExclusionList exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
DWORD CmdBWConservationList( PWSTR BWConservationListArg) { HSHADOW hDir; SHADOWINFO sSI; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = 0; ULONG hShare;
if (fSwDebug == TRUE) MyPrintf(L"CmdBWConservationList(%ws)\r\n", BWConservationListArg);
if (BWConservationListArg == NULL) { BWConservationListArg = L" "; }
MyPrintf(L"Setting BWConservation list to \"%ws\"\r\n", BWConservationListArg);
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdBWConservationList:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
memset(&sSI, 0, sizeof(SHADOWINFO)); sSI.uSubOperation = SHADOW_SET_BW_CONSERVE_LIST; sSI.lpBuffer = BWConservationListArg; sSI.cbBufferSize = (wcslen(BWConservationListArg)+1) * sizeof(WCHAR);
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_DO_SHADOW_MAINTENANCE, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdBWConservationList exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
DWORD CmdDetector( VOID) { HSHADOW hDir; SHADOWINFO sSI; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = ERROR_SUCCESS; ULONG hShare;
if (fSwDebug == TRUE) MyPrintf(L"CmdDetector()\r\n");
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdDetector:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
memset(&sSI, 0, sizeof(SHADOWINFO)); sSI.uSubOperation = SHADOW_SPARSE_STALE_DETECTION_COUNTER;
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_DO_SHADOW_MAINTENANCE, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (bResult) MyPrintf(L"%d\r\n", sSI.dwError); else Status = sSI.dwError;
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdDetector exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
DWORD CmdSwitches( VOID) { HSHADOW hDir; SHADOWINFO sSI; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = ERROR_SUCCESS; ULONG hShare;
if (fSwDebug == TRUE) MyPrintf(L"CmdSwitches()\r\n");
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdSwitches:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
memset(&sSI, 0, sizeof(SHADOWINFO)); sSI.uOp = SHADOW_SWITCH_GET_STATE;
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_SWITCHES, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (bResult) { MyPrintf(L"0x%08x", sSI.uStatus); if (sSI.uStatus != 0) { MyPrintf(L" ("); if (sSI.uStatus & SHADOW_SWITCH_SHADOWING) MyPrintf(L"SHADOW_SWITCH_SHADOWING "); if (sSI.uStatus & SHADOW_SWITCH_LOGGING) MyPrintf(L"SHADOW_SWITCH_LOGGING "); if (sSI.uStatus & SHADOW_SWITCH_SPEAD_OPTIMIZE) MyPrintf(L"SHADOW_SWITCH_SPEAD_OPTIMIZE "); MyPrintf(L")"); } if ((sSI.uStatus & SHADOW_SWITCH_SHADOWING) == 0) MyPrintf(L" ... csc is disabled"); else MyPrintf(L" ... csc is enabled"); MyPrintf(L"\r\n"); } else { Status = sSI.dwError; }
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdSwitches exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
DWORD CmdGetSpace( VOID) { DWORD Error = ERROR_SUCCESS; WCHAR szVolume[MAX_PATH]; LARGE_INTEGER MaxSpace; LARGE_INTEGER CurrentSpace; DWORD TotalFiles; DWORD TotalDirs; BOOL fRet;
if (fSwDebug == TRUE) MyPrintf(L"CmdGetSpace()\r\n");
fRet = CSCGetSpaceUsageW( szVolume, sizeof(szVolume)/sizeof(WCHAR), &MaxSpace.HighPart, &MaxSpace.LowPart, &CurrentSpace.HighPart, &CurrentSpace.LowPart, &TotalFiles, &TotalDirs);
if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
MyPrintf( L"Volume: %ws\r\n" L"MaxSpace: 0x%x:0x%x (%d)\r\n" L"CurrentSpace: 0x%x:0x%x (%d)\r\n" L"TotalFiles: %d\r\n" L"TotalDirs: %d\r\n", szVolume, MaxSpace.HighPart, MaxSpace.LowPart, MaxSpace.LowPart, CurrentSpace.HighPart, CurrentSpace.LowPart, CurrentSpace.LowPart, TotalFiles, TotalDirs);
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdGetSpace exit %d\r\n", Error);
return Error; }
DWORD CmdIsServerOffline( PWSTR IsServerOfflineArg) { DWORD Error = ERROR_SUCCESS; BOOL fRet; BOOL fOffline = FALSE;
if (fSwDebug == TRUE) MyPrintf(L"CmdIsServerOffline(%ws)\r\n", IsServerOfflineArg);
fRet = CSCIsServerOfflineW( IsServerOfflineArg, &fOffline);
if (fRet == FALSE) { Error = GetLastError(); goto AllDone; }
if (fOffline == TRUE) MyPrintf(L"Offline\r\n"); else MyPrintf(L"Online\r\n");
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdIsServerOffline exit %d\r\n", Error);
return Error; }
DWORD CmdSetShareStatus( PWSTR SetShareStatusArg) { HSHADOW hDir; SHADOWINFO sSI; BOOL bResult; HANDLE hDBShadow = INVALID_HANDLE_VALUE; ULONG junk; ULONG Status = 0; ULONG StatusToSet = 0; ULONG hShare = 0;
if (fSwDebug == TRUE) MyPrintf(L"CmdSetShareStatus(%ws)\r\n", SetShareStatusArg);
if (fSwSet == TRUE && fSwClear == TRUE) { MyPrintf(L"Can't have both SET and CLEAR\r\n"); Status = ERROR_INVALID_PARAMETER; goto AllDone; }
hDBShadow = CreateFile( L"\\\\.\\shadow", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDBShadow == INVALID_HANDLE_VALUE) { MyPrintf(L"CmdSetShareStatus:Failed open of shadow device\r\n"); Status = GetLastError(); goto AllDone; }
swscanf(SetShareStatusArg, L"%x:%x", &hShare, &StatusToSet);
if (fSwDebug == TRUE) MyPrintf(L"CmdSetShareStatus hShare=0x%x StatusToSet=0x%x\r\n", hShare, StatusToSet);
memset(&sSI, 0, sizeof(SHADOWINFO)); sSI.hShare = hShare; if (fSwSet == TRUE) { sSI.uStatus = StatusToSet; sSI.uOp = SHADOW_FLAGS_OR; } else if (fSwClear == TRUE) { sSI.uStatus = ~StatusToSet; sSI.uOp = SHADOW_FLAGS_AND; } else { MyPrintf(L"Missing /SET or /CLEAR\r\n"); Status = ERROR_INVALID_PARAMETER; goto AllDone; }
bResult = DeviceIoControl( hDBShadow, // device
IOCTL_SET_SHARE_STATUS, // control code
(LPVOID)&sSI, // in buffer
0, // inbuffer size
NULL, // out buffer
0, // out buffer size
&junk, // bytes returned
NULL); // overlapped
if (!bResult) { MyPrintf(L"CmdSetShareStatus:DeviceIoControl IOCTL_SET_SHARE_STATUS failed\n"); Status = GetLastError(); goto AllDone; }
AllDone:
if (fSwDebug == TRUE) MyPrintf(L"CmdSetShareStatus exit %d\r\n", Status);
if (hDBShadow != INVALID_HANDLE_VALUE) CloseHandle(hDBShadow);
return Status; }
#define MAX_OFFSETS 256
#define PAGESIZE 4096
ULONG OffsetArgs[MAX_OFFSETS];
DWORD CmdRandW( PWSTR CmdRandWArg) {
DWORD dwError = ERROR_SUCCESS; DWORD dwFileSize; DWORD dwOffset; DWORD dwOffsetHigh; UCHAR uchData; HANDLE hFile = INVALID_HANDLE_VALUE; ULONG i; LONG WriteCount = 0; LONG PageCount = 0; PBYTE wArray = NULL;
if (fSwDebug == TRUE) { MyPrintf(L"CmdRandW(%ws)\r\n", CmdRandWArg); if (fArgOffset == TRUE) MyPrintf(L" OFFSET [%ws]\r\n", pwszOffsetArg); }
srand( (unsigned)time( NULL ) );
hFile = CreateFileW( CmdRandWArg, // name
GENERIC_READ|GENERIC_WRITE, // access mode
FILE_SHARE_READ|FILE_SHARE_WRITE, // share mode
NULL, // security descriptor
OPEN_EXISTING, // create disposition
0, // file statributes if created
NULL); // template handle
if (hFile == INVALID_HANDLE_VALUE) { dwError = GetLastError(); goto AllDone; } dwFileSize = GetFileSize(hFile, NULL); MyPrintf(L"File size = %d bytes\r\n", dwFileSize);
if (fArgOffset == TRUE) { WriteCount = CountOffsetArgs(pwszOffsetArg, OffsetArgs); if (WriteCount == 0) { MyPrintf(L"No offsets specified, or - nothing to do.\r\n"); goto AllDone; } else if (WriteCount < 0) { MyPrintf(L"Error in offset list. Exiting.\r\n"); dwError = ERROR_INVALID_PARAMETER; goto AllDone; } } else { PageCount = (dwFileSize / PAGESIZE); WriteCount = rand() % PageCount; } if (fSwDebug == TRUE) { wArray = calloc(1, PageCount * sizeof(BYTE)); MyPrintf(L"There are %d pages in the file\r\n", PageCount); } if (dwFileSize == -1) { dwError = GetLastError(); if (fSwDebug == TRUE) MyPrintf(L"GetFileSize() failed %d\r\n", dwError); goto AllDone; } if (dwFileSize == 0) { MyPrintf(L"0 sized file - nothing to do.\r\n"); goto AllDone; } MyPrintf(L"Writing %d times\r\n", WriteCount); for (i = 0; i < (ULONG)WriteCount; ++i) { DWORD dwReturn; if (fArgOffset == TRUE) dwOffset = OffsetArgs[i]; else dwOffset = ((rand() % PageCount) * PAGESIZE) + (rand() % PAGESIZE); uchData = (UCHAR)rand(); if (SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { dwError = GetLastError(); if (fSwDebug == TRUE) MyPrintf(L"SetFilePointer() failed %d\r\n", dwError); goto AllDone; } MyPrintf(L"writing 0x02%x Page %d offset %d (offset %d(0x%x))\r\n", uchData, dwOffset / PAGESIZE, dwOffset % PAGESIZE, dwOffset, dwOffset); if (wArray) wArray[dwOffset/PAGESIZE]++; if (!WriteFile(hFile, &uchData, 1, &dwReturn, NULL)) { dwError = GetLastError(); if (fSwDebug == TRUE) MyPrintf(L"WriteFile() failed %d\r\n", dwError); goto AllDone; } }
if (wArray) { for (i = 0; i < (ULONG)PageCount; i++) { MyPrintf(L"%d", wArray[i]); if ((i % 50) == 0) MyPrintf(L"\r\n"); } MyPrintf(L"\r\n"); }
// If EOF is specified, truncate the file to a random length
if (fSwEof == TRUE) { ULONG xx = rand() % 5; ULONG NewLen = (rand() * rand()) % (dwFileSize * 2); if (xx == 0 || xx == 1) { MyPrintf(L"New EOF = %d\r\n", NewLen); SetFilePointer(hFile, NewLen, 0, FILE_BEGIN); SetEndOfFile(hFile); } else { MyPrintf(L"No EOF change.\r\n"); } }
AllDone: if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); if (wArray) free(wArray); if (fSwDebug == TRUE) MyPrintf(L"CmdRandW exit %d\r\n", dwError); return dwError; }
LONG CountOffsetArgs( PWSTR OffsetArg, ULONG OffsetArray[]) { // Expect a string of the form "N,N,N,N" where each N can be hex OR decimal.
// Store results in OffsetArray[]
// Limit is MAX_OFFSETS offsets, to make things easy.
ULONG i; PWCHAR wCp = OffsetArg; PWCHAR wNum = NULL; ULONG iRet;
for (i = 0; i < MAX_OFFSETS; i++) { if (*wCp == L'\0') break; wNum = wCp; while (*wCp != L',' && *wCp != L'\0') wCp++; if (*wCp == L',') *wCp++ = L'\0'; iRet = swscanf(wNum, L"%Li", &OffsetArray[i]); if (iRet <= 0) return -1; } if (fSwDebug == TRUE) { ULONG j; for (j = 0; j < i; j++) MyPrintf(L"[%d]-0x%x(%d)\r\n", j, OffsetArray[j], OffsetArray[j]); MyPrintf(L"CountOffsetArgs returning %d\r\n", i); } return i; }
#if defined(CSCUTIL_INTERNAL)
DWORD CmdBitcopy( PWSTR BitcopyArg) { DWORD Error = ERROR_FILE_NOT_FOUND; LPWSTR lpszTempName = NULL;
if (!CSCCopyReplicaW(BitcopyArg, &lpszTempName)) { Error = GetLastError(); } else { Error = ERROR_SUCCESS; }
if (Error == ERROR_SUCCESS) { Error = DumpBitMap(lpszTempName); DeleteFile(lpszTempName); }
return Error; } #endif // CSCUTIL_INTERNAL
|