2136 lines
69 KiB
C++
2136 lines
69 KiB
C++
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1996.
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
#include <pch.cxx>
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <ole2.h>
|
||
|
|
||
|
#define TRKDATA_ALLOCATE
|
||
|
#include "trkwks.hxx"
|
||
|
#include "trksvr.hxx"
|
||
|
#include "dltadmin.hxx"
|
||
|
|
||
|
|
||
|
OLECHAR *
|
||
|
tcstoocs(OLECHAR *poszBuf, const TCHAR *ptsz)
|
||
|
{
|
||
|
#ifdef OLE2ANSI
|
||
|
return tcstombs( poszBuf, ptsz );
|
||
|
#else
|
||
|
return tcstowcs( poszBuf, ptsz );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
TCHAR *
|
||
|
ocstotcs(TCHAR *ptszBuf, const OLECHAR *posz)
|
||
|
{
|
||
|
#ifdef OLE2ANSI
|
||
|
return mbstotcs( ptszBuf, posz );
|
||
|
#else
|
||
|
return wcstotcs( ptszBuf, posz );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void Usage()
|
||
|
{
|
||
|
printf( "\nDistributed Link Tracking service admin tools\n"
|
||
|
"\n"
|
||
|
"Usage: dltadmin [command command-parameters]\n"
|
||
|
"For help: dltadmin [command] -?\n"
|
||
|
"Commands: -VolInfoFile (get volume info from a file path)\n"
|
||
|
" -VolStat (volume statistics)\n"
|
||
|
" -FileOid (set/get/use file Object IDs)\n"
|
||
|
" -EnumOids (enumerate object IDs)\n"
|
||
|
" -OidSnap (save/restore all OIDs)\n"
|
||
|
" -Link (create/resolve shell link)\n"
|
||
|
" -VolId (get/set volume IDs)\n"
|
||
|
" -CleanVol (clean Object/Volume IDs)\n"
|
||
|
" -LockVol (lock/dismount a volume)\n"
|
||
|
" -SvrStat (trkSvr statistics)\n"
|
||
|
" -LoadLib (load a dll into a process)\n"
|
||
|
" -FreeLib (unload a dll from a process)\n"
|
||
|
" -Config (configure the registry and/or runing service)\n"
|
||
|
" -Refresh (refresh the trkwks volume list)\n"
|
||
|
" -DebugBreak (break into a process)\n"
|
||
|
" -LookupVolId (look up entry in DC volume table)\n"
|
||
|
" -LookupDroid (look up entry in DC move table)\n"
|
||
|
" -DelDcMoveId (del move table entry from DC)\n"
|
||
|
" -DelDcVolId (del volume table entry from DC)\n"
|
||
|
" -SetVolSeq (set volid sequence number)\n"
|
||
|
" -SetDroidSeq (set move entry sequence number)\n" );
|
||
|
}
|
||
|
|
||
|
|
||
|
// Dummy function to make it link
|
||
|
void
|
||
|
ServiceStopCallback( PVOID pContext, BOOLEAN fTimeout )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
TSZ2CLSID( const LPTSTR tszCLSID, CLSID *pclsid )
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
OLECHAR oszCLSID[ CCH_GUID_STRING + 1 ];
|
||
|
|
||
|
tcstoocs( oszCLSID, tszCLSID );
|
||
|
|
||
|
hr = CLSIDFromString( oszCLSID, pclsid );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't convert string to CLSID") ));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DltAdminLockVol( ULONG cArgs, TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
NTSTATUS status = 0;
|
||
|
ULONG iVolume = static_cast<ULONG>(-1);
|
||
|
TCHAR tszVolume[ ] = TEXT("\\\\.\\A:");
|
||
|
OBJECT_ATTRIBUTES ObjAttr;
|
||
|
IO_STATUS_BLOCK Iosb;
|
||
|
UNICODE_STRING uPath;
|
||
|
HANDLE hVolume = NULL;
|
||
|
BOOL fSuccess = FALSE;
|
||
|
CHAR rgcCommands[ 10 ];
|
||
|
ULONG iCommand = 0, cCommands = 0;
|
||
|
|
||
|
|
||
|
*pcEaten = 0;
|
||
|
|
||
|
if( 0 == cArgs
|
||
|
||
|
||
|
1 <= cArgs && IsHelpArgument(rgptszArgs[0]) )
|
||
|
{
|
||
|
*pcEaten = 1;
|
||
|
printf( "\nOption LockVol\n"
|
||
|
" Purpose: Lock and/or dismount a volume\n"
|
||
|
" Usage: -LockVol <options> <drive letter>:\n"
|
||
|
" Where: <options> are any combination (up to %d) of:\n"
|
||
|
" -d Send FSCTL_DISMOUNT_VOLUME\n"
|
||
|
" -l Send FSCTL_LOCK_VOLUME\n"
|
||
|
" -u Send FSCTL_UNLOCK_VOLUME\n"
|
||
|
" -p Pause for user input\n"
|
||
|
" E.g.: -LockVol -d -l -u c:\n"
|
||
|
" -LockVol -l c:\n",
|
||
|
ELEMENTS(rgcCommands) );
|
||
|
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
for( int iArgs = 0; iArgs < cArgs; iArgs++ )
|
||
|
{
|
||
|
if( 2 == _tcslen( rgptszArgs[iArgs] ) && TEXT(':') == rgptszArgs[iArgs][1] )
|
||
|
{
|
||
|
TCHAR tc = rgptszArgs[iArgs][0];
|
||
|
if( TEXT('A') <= tc && TEXT('Z') >= tc )
|
||
|
iVolume = tc - TEXT('A');
|
||
|
else if( TEXT('a') <= tc && TEXT('z') >= tc )
|
||
|
iVolume = tc - TEXT('a');
|
||
|
}
|
||
|
else if( TEXT('-') == rgptszArgs[iArgs][0]
|
||
|
||
|
||
|
TEXT('/') == rgptszArgs[iArgs][0] )
|
||
|
{
|
||
|
_tcslwr(rgptszArgs[iArgs]);
|
||
|
|
||
|
if( iCommand >= ELEMENTS(rgcCommands) )
|
||
|
{
|
||
|
printf( "Too many commands to LockVol. Use -? for usage info.\n" );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
if( TEXT('d') == rgptszArgs[iArgs][1] )
|
||
|
rgcCommands[iCommand] = 'd';
|
||
|
else
|
||
|
if( TEXT('l') == rgptszArgs[iArgs][1] )
|
||
|
rgcCommands[iCommand] = 'l';
|
||
|
else
|
||
|
if( TEXT('u') == rgptszArgs[iArgs][1] )
|
||
|
rgcCommands[iCommand] = 'u';
|
||
|
else
|
||
|
if( TEXT('p') == rgptszArgs[iArgs][1] )
|
||
|
rgcCommands[iCommand] = 'p';
|
||
|
else
|
||
|
{
|
||
|
printf( "Invalid option. Use -? for usage info.\n" );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cCommands++;
|
||
|
iCommand++;
|
||
|
(*pcEaten)++;
|
||
|
}
|
||
|
|
||
|
if( static_cast<ULONG>(-1) == iVolume )
|
||
|
{
|
||
|
printf( "Invalid parameter. Use -? for usage info\n" );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
|
||
|
tszVolume[4] += static_cast<TCHAR>(iVolume);
|
||
|
|
||
|
if( !RtlDosPathNameToNtPathName_U( tszVolume, &uPath, NULL, NULL ))
|
||
|
{
|
||
|
status = STATUS_OBJECT_NAME_INVALID;
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
InitializeObjectAttributes(
|
||
|
&ObjAttr,
|
||
|
&uPath,
|
||
|
OBJ_CASE_INSENSITIVE,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
status = NtOpenFile(
|
||
|
&hVolume,
|
||
|
FILE_READ_DATA|FILE_WRITE_DATA|SYNCHRONIZE,
|
||
|
&ObjAttr,
|
||
|
&Iosb,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||
|
FILE_SYNCHRONOUS_IO_ALERT
|
||
|
);
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
printf( "Failed NtOpenFile of %s (%08x)\n", tszVolume, status );
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
|
||
|
for( iCommand = 0; iCommand < cCommands; iCommand++ )
|
||
|
{
|
||
|
switch( rgcCommands[iCommand] )
|
||
|
{
|
||
|
case 'd':
|
||
|
{
|
||
|
status = NtFsControlFile(
|
||
|
hVolume,
|
||
|
NULL, /* Event */
|
||
|
NULL, /* ApcRoutine */
|
||
|
NULL, /* ApcContext */
|
||
|
&Iosb,
|
||
|
FSCTL_DISMOUNT_VOLUME,
|
||
|
NULL, /* InputBuffer */
|
||
|
0, /* InputBufferLength */
|
||
|
NULL, /* OutputBuffer */
|
||
|
0 /* OutputBufferLength */
|
||
|
);
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
printf( "Failed FSCTL_DISMOUNT_VOLUME (%08x)\n", status );
|
||
|
else
|
||
|
printf( "Volume dismounted\n" );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'l':
|
||
|
{
|
||
|
status = NtFsControlFile(
|
||
|
hVolume,
|
||
|
NULL, /* Event */
|
||
|
NULL, /* ApcRoutine */
|
||
|
NULL, /* ApcContext */
|
||
|
&Iosb,
|
||
|
FSCTL_LOCK_VOLUME,
|
||
|
NULL, /* InputBuffer */
|
||
|
0, /* InputBufferLength */
|
||
|
NULL, /* OutputBuffer */
|
||
|
0 /* OutputBufferLength */
|
||
|
);
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
printf( "Failed FSCTL_LOCK_VOLUME (%08x)\n", status );
|
||
|
else
|
||
|
printf( "Volume is locked\n" );
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'u':
|
||
|
{
|
||
|
status = NtFsControlFile(
|
||
|
hVolume,
|
||
|
NULL, /* Event */
|
||
|
NULL, /* ApcRoutine */
|
||
|
NULL, /* ApcContext */
|
||
|
&Iosb,
|
||
|
FSCTL_UNLOCK_VOLUME,
|
||
|
NULL, /* InputBuffer */
|
||
|
0, /* InputBufferLength */
|
||
|
NULL, /* OutputBuffer */
|
||
|
0 /* OutputBufferLength */
|
||
|
);
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
printf( "Failed FSCTL_UNLOCK_VOLUME (%08x)\n", status );
|
||
|
else
|
||
|
printf( "Volume unlocked\n" );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'p':
|
||
|
{
|
||
|
printf( "Press enter to unlock ..." );
|
||
|
getchar();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
} // switch( rgcCommands[iCommand] )
|
||
|
} // for( iCommand = 0; iCommand < cCommands; iCommand++ )
|
||
|
|
||
|
fSuccess = TRUE;
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
return( fSuccess );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
MakeAbsolutePath( TCHAR * ptszAbsolute, TCHAR * ptszRelative )
|
||
|
{
|
||
|
|
||
|
if( !_tcsncmp( TEXT("\\\\"), ptszRelative, 2 ) // A UNC path
|
||
|
||
|
||
|
TEXT(':') == ptszRelative[1] ) // A drive-based path
|
||
|
{
|
||
|
// The command-line has an absolute path
|
||
|
_tcscpy( ptszAbsolute, ptszRelative );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// The command-line has a relative path
|
||
|
|
||
|
DWORD dwLength = 0;
|
||
|
|
||
|
dwLength = GetCurrentDirectory( MAX_PATH, ptszAbsolute );
|
||
|
if( 0 == dwLength )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't get current directory") ));
|
||
|
TrkRaiseLastError( );
|
||
|
}
|
||
|
if( TEXT('\\') != ptszAbsolute[dwLength-1] )
|
||
|
_tcscat( ptszAbsolute, TEXT("\\") );
|
||
|
|
||
|
_tcscat( ptszAbsolute, ptszRelative );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DltAdminFileOid( ULONG cArgs, TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
NTSTATUS status = 0;
|
||
|
TCHAR tszFile[ MAX_PATH + 1 ];
|
||
|
WCHAR wszFile[ MAX_PATH + 1 ];
|
||
|
TCHAR tszUNCPath[ MAX_PATH + 1 ];
|
||
|
WCHAR wszOID[ CCH_GUID_STRING + 1 ];
|
||
|
ULONG cbInBuffer;
|
||
|
TCHAR tszMachineName[ MAX_PATH + 1 ];
|
||
|
LPCTSTR tszVolumePath = NULL;
|
||
|
USHORT iVolume;
|
||
|
|
||
|
OLECHAR oszOID[ CCH_GUID_STRING + 1 ];
|
||
|
|
||
|
EnablePrivilege( SE_RESTORE_NAME );
|
||
|
|
||
|
*pcEaten = 0;
|
||
|
|
||
|
// -------------------------
|
||
|
// Validate the command-line
|
||
|
// -------------------------
|
||
|
|
||
|
if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] ))
|
||
|
{
|
||
|
*pcEaten = 1;
|
||
|
printf( "\nOption FileOID\n"
|
||
|
" Purpose: Get/set/use file Object IDs\n"
|
||
|
" Usage: -fileoid <option> <filename or object id, depending on the option>\n"
|
||
|
" Options: -r => Read the object ID from a file\n"
|
||
|
" -g => Get (creating if necessary) the object ID from a file\n"
|
||
|
" -f => Search the local machine for an object ID's filename\n"
|
||
|
" -s => Set an ID on a file (specify objid, then filename)\n"
|
||
|
" -sr => Make a file reborn\n"
|
||
|
" -df => Delete the object ID from it's file, given the filename\n"
|
||
|
" -do => Delete the object ID from it's file, given the object ID\n"
|
||
|
" E.g.: -fileoid -g d:\\test.txt\n"
|
||
|
" -fileoid -r d:\\test.txt\n"
|
||
|
" -fileoid -f {C69F3AA6-8B4C-11D0-8C9D-00C04FD90F85}\n"
|
||
|
" -fileoid -do {C69F3AA6-8B4C-11D0-8C9D-00C04FD90F85}\n"
|
||
|
" -fileoid -df d:\\test.txt\n" );
|
||
|
return( TRUE );
|
||
|
}
|
||
|
else
|
||
|
if( 2 > cArgs
|
||
|
||
|
||
|
rgptszArgs[0][0] != TEXT('-')
|
||
|
&&
|
||
|
rgptszArgs[0][0] != TEXT('/')
|
||
|
)
|
||
|
{
|
||
|
printf( "Parameter error. Use -? for usage info\n" );
|
||
|
}
|
||
|
|
||
|
*pcEaten = 2;
|
||
|
|
||
|
// Convert the option to upper case (options are case-insensitive).
|
||
|
_tcsupr( rgptszArgs[0] );
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
// Switch on the option (e.g, the 'F' in "-F")
|
||
|
|
||
|
switch( rgptszArgs[0][1] )
|
||
|
{
|
||
|
|
||
|
// --------------------------------
|
||
|
// Get a file name from an ObjectID
|
||
|
// --------------------------------
|
||
|
|
||
|
case TEXT('F'):
|
||
|
{
|
||
|
CDomainRelativeObjId droidBirth;
|
||
|
|
||
|
// Get the OID in binary format
|
||
|
CObjId oid;
|
||
|
TSZ2CLSID( rgptszArgs[1], (GUID*)&oid );
|
||
|
|
||
|
// Scan the volumes for this objectID
|
||
|
|
||
|
for (LONG vol = 0; vol < 26; vol++)
|
||
|
{
|
||
|
if( IsLocalObjectVolume( vol )
|
||
|
&&
|
||
|
NT_SUCCESS(FindLocalPath(vol, oid, &droidBirth, &tszUNCPath[2])) )
|
||
|
{
|
||
|
tszUNCPath[0] = VolChar(vol);
|
||
|
tszUNCPath[1] = TEXT(':');
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( 'z'-'a' == vol )
|
||
|
{
|
||
|
hr = ERROR_FILE_NOT_FOUND;
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
// Display the filename
|
||
|
|
||
|
wprintf( L"File name = \"%s\"\n", tszUNCPath );
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
|
||
|
// --------------------
|
||
|
// Read/Get an ObjectID
|
||
|
// --------------------
|
||
|
|
||
|
case TEXT('R'):
|
||
|
case TEXT('G'):
|
||
|
|
||
|
{
|
||
|
|
||
|
TCHAR tszFile[ MAX_PATH + 1 ];
|
||
|
|
||
|
MakeAbsolutePath( tszFile, rgptszArgs[1] );
|
||
|
|
||
|
CDomainRelativeObjId droidCurrent;
|
||
|
CDomainRelativeObjId droidBirth;
|
||
|
|
||
|
status = GetDroids( tszFile, &droidCurrent, &droidBirth,
|
||
|
rgptszArgs[0][1] == TEXT('R') ? RGO_READ_OBJECTID : RGO_GET_OBJECTID );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
hr = status;
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("Current:\n") );
|
||
|
_tprintf( TEXT(" volid = %s\n"),
|
||
|
static_cast<const TCHAR*>(CStringize(droidCurrent.GetVolumeId() )));
|
||
|
_tprintf( TEXT(" objid = %s\n"),
|
||
|
static_cast<const TCHAR*>(CStringize(droidCurrent.GetObjId() )));
|
||
|
|
||
|
_tprintf( TEXT("Birth:\n") );
|
||
|
_tprintf( TEXT(" volid = %s\n"),
|
||
|
static_cast<const TCHAR*>(CStringize(droidBirth.GetVolumeId() )));
|
||
|
_tprintf( TEXT(" objid = %s\n"),
|
||
|
static_cast<const TCHAR*>(CStringize(droidBirth.GetObjId() )));
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
// ---------------
|
||
|
// Set an ObjectID
|
||
|
// ---------------
|
||
|
|
||
|
case TEXT('S'):
|
||
|
|
||
|
{
|
||
|
HANDLE hFile;
|
||
|
CObjId objid;
|
||
|
IO_STATUS_BLOCK IoStatus;
|
||
|
TCHAR tszFile[ MAX_PATH + 1 ];
|
||
|
|
||
|
if( TEXT('R') == rgptszArgs[0][2] )
|
||
|
{
|
||
|
if( 2 > cArgs )
|
||
|
{
|
||
|
printf( "Parameter error. Use -? for usage info\n" );
|
||
|
hr = E_FAIL;
|
||
|
goto Exit;
|
||
|
}
|
||
|
(*pcEaten)++;
|
||
|
|
||
|
MakeAbsolutePath( tszFile, rgptszArgs[1] );
|
||
|
|
||
|
status = TrkCreateFile( tszFile, FILE_READ_ATTRIBUTES,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
|
||
|
FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_NO_RECALL | FILE_SYNCHRONOUS_IO_NONALERT,
|
||
|
NULL,
|
||
|
&hFile );
|
||
|
if (!NT_SUCCESS(status))
|
||
|
{
|
||
|
printf( "TrkCreateFile failed\n" );
|
||
|
hr = status;
|
||
|
__leave;
|
||
|
}
|
||
|
status = MakeObjIdReborn( hFile );
|
||
|
if( NT_SUCCESS(status) )
|
||
|
printf( "File is reborn\n" );
|
||
|
else
|
||
|
printf( "Failed to make reborn (%08x)\n", status );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TSZ2CLSID( rgptszArgs[1], (GUID*)&objid );
|
||
|
|
||
|
if( 3 > cArgs )
|
||
|
{
|
||
|
printf( "Parameter error. Use -? for usage info\n" );
|
||
|
hr = E_FAIL;
|
||
|
goto Exit;
|
||
|
}
|
||
|
(*pcEaten)++;
|
||
|
|
||
|
MakeAbsolutePath( tszFile, rgptszArgs[2] );
|
||
|
|
||
|
status = TrkCreateFile( tszFile, FILE_READ_ATTRIBUTES,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
|
||
|
FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_NO_RECALL | FILE_SYNCHRONOUS_IO_NONALERT,
|
||
|
NULL,
|
||
|
&hFile );
|
||
|
if (!NT_SUCCESS(status))
|
||
|
{
|
||
|
printf( "TrkCreateFile failed\n" );
|
||
|
hr = status;
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
status = SetObjId( hFile, objid, CDomainRelativeObjId() );
|
||
|
|
||
|
if (!NT_SUCCESS(status))
|
||
|
{
|
||
|
printf( "FSCTL_SET_OBJECT_ID failed\n" );
|
||
|
hr = status;
|
||
|
__leave;
|
||
|
}
|
||
|
printf( "ID set ok\n" );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case TEXT('D'):
|
||
|
{
|
||
|
if( TEXT('F') == rgptszArgs[0][2] )
|
||
|
{
|
||
|
TCHAR tszFile[ MAX_PATH + 1 ];
|
||
|
HANDLE hFile;
|
||
|
NTSTATUS status;
|
||
|
IO_STATUS_BLOCK IoStatus;
|
||
|
|
||
|
MakeAbsolutePath( tszFile, rgptszArgs[1] );
|
||
|
|
||
|
status = TrkCreateFile( tszFile, FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
|
||
|
FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_NO_RECALL | FILE_SYNCHRONOUS_IO_NONALERT,
|
||
|
NULL,
|
||
|
&hFile );
|
||
|
if (!NT_SUCCESS(status))
|
||
|
{
|
||
|
printf( "TrkCreateFile failed\n" );
|
||
|
hr = status;
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
status = NtFsControlFile(
|
||
|
hFile,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&IoStatus,
|
||
|
FSCTL_DELETE_OBJECT_ID,
|
||
|
NULL, // in buffer
|
||
|
0, // in buffer size
|
||
|
NULL, // Out buffer
|
||
|
0); // Out buffer size
|
||
|
|
||
|
if (!NT_SUCCESS(status))
|
||
|
{
|
||
|
printf( "FSCTL_DELETE_OBJECT_ID failed\n" );
|
||
|
hr = status;
|
||
|
__leave;
|
||
|
}
|
||
|
printf( "Deleted ok\n" );
|
||
|
|
||
|
}
|
||
|
|
||
|
else if( TEXT('O') == rgptszArgs[0][2] )
|
||
|
{
|
||
|
// Get the OID in binary format
|
||
|
CObjId oid;
|
||
|
CDomainRelativeObjId droidBirth;
|
||
|
TSZ2CLSID( rgptszArgs[1], (GUID*)&oid );
|
||
|
BOOL fFound = FALSE;
|
||
|
|
||
|
for (int vol='a'-'a'; vol<'z'-'a'; vol++)
|
||
|
{
|
||
|
if( IsLocalObjectVolume(CVolumeDeviceName(vol)) )
|
||
|
{
|
||
|
status = FindLocalPath(vol, oid, &droidBirth, &tszUNCPath[2]);
|
||
|
if( STATUS_OBJECT_NAME_NOT_FOUND == status )
|
||
|
continue;
|
||
|
if( !NT_SUCCESS(status) ) goto Exit;
|
||
|
|
||
|
tszUNCPath[0] = VolChar(vol);
|
||
|
tszUNCPath[1] = TEXT(':');
|
||
|
|
||
|
_tprintf( TEXT("Deleting object ID on %s\n"), tszUNCPath );
|
||
|
|
||
|
status = DelObjId( vol, oid );
|
||
|
if( !NT_SUCCESS(status) ) goto Exit;
|
||
|
printf( "Deleted ok\n" );
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( fFound ) printf( "Not found\n" );
|
||
|
}
|
||
|
else
|
||
|
printf( "Bad parameter\n" );
|
||
|
} // case TEXT('D'):
|
||
|
break;
|
||
|
|
||
|
|
||
|
} // switch
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
} // __try
|
||
|
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
printf( "HR = %08X\n", hr );
|
||
|
|
||
|
return SUCCEEDED(hr);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DltAdminTemp( ULONG cArgs, TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
RPC_STATUS rpcstatus;
|
||
|
RPC_TCHAR * ptszStringBinding;
|
||
|
RPC_BINDING_HANDLE hBinding = NULL;
|
||
|
BOOL fBound = FALSE;
|
||
|
LONG iVol = 4;
|
||
|
GUID volid = { /* 9f1534ee-ceab-4710-98b9-daaf048e3ad2 */
|
||
|
0x9f1534ee,
|
||
|
0xceab,
|
||
|
0x4710,
|
||
|
{0x98, 0xb9, 0xda, 0xaf, 0x04, 0x8e, 0x3a, 0xd2}
|
||
|
};
|
||
|
|
||
|
if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] ))
|
||
|
{
|
||
|
printf("\nOption Refresh\n"
|
||
|
" Purpose: Temp test placeholder\n"
|
||
|
" Usage: -temp\n" );
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
|
||
|
rpcstatus = RpcStringBindingCompose( NULL, TEXT("ncalrpc"), NULL, TEXT("trkwks"),
|
||
|
NULL, &ptszStringBinding);
|
||
|
|
||
|
if( rpcstatus )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Failed RpcStringBindingCompose %lu"), rpcstatus ));
|
||
|
hr = HRESULT_FROM_WIN32(rpcstatus);
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
rpcstatus = RpcBindingFromStringBinding( ptszStringBinding, &hBinding );
|
||
|
RpcStringFree( &ptszStringBinding );
|
||
|
|
||
|
if( rpcstatus )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Failed RpcBindingFromStringBinding") ));
|
||
|
hr = HRESULT_FROM_WIN32(rpcstatus);
|
||
|
goto Exit;
|
||
|
}
|
||
|
fBound = TRUE;
|
||
|
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
hr = LnkSetVolumeId( hBinding, iVol, volid );
|
||
|
}
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( GetExceptionCode() );
|
||
|
}
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
_tprintf( TEXT("Failed call to service (%08x)\n"), hr );
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( fBound )
|
||
|
RpcBindingFree( &hBinding );
|
||
|
|
||
|
return( TRUE );
|
||
|
|
||
|
} // main()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
CVolumeId
|
||
|
DisplayLogStatus( LONG iVol )
|
||
|
{
|
||
|
NTSTATUS status = STATUS_SUCCESS;
|
||
|
HANDLE hFile = NULL;
|
||
|
TCHAR tszLog[ MAX_PATH + 1 ];
|
||
|
|
||
|
ULONG cbRead;
|
||
|
LogHeader logheader;
|
||
|
LogInfo loginfo;
|
||
|
VolumePersistentInfo volinfo;
|
||
|
|
||
|
_tcscpy( tszLog, CVolumeDeviceName(iVol) );
|
||
|
_tcscat( tszLog, s_tszLogFileName );
|
||
|
|
||
|
status = TrkCreateFile( tszLog, FILE_GENERIC_READ, FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
|
||
|
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, &hFile );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't open %s"), tszLog ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
|
||
|
if( !ReadFile( hFile, &logheader, sizeof(logheader), &cbRead, NULL )
|
||
|
||
|
||
|
sizeof(logheader) != cbRead )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't read log header") ));
|
||
|
TrkRaiseLastError();
|
||
|
}
|
||
|
|
||
|
if( !ReadFile( hFile, &volinfo, sizeof(volinfo), &cbRead, NULL )
|
||
|
||
|
||
|
sizeof(volinfo) != cbRead )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't read volinfo") ));
|
||
|
TrkRaiseLastError();
|
||
|
}
|
||
|
|
||
|
if( !ReadFile( hFile, &loginfo, sizeof(loginfo), &cbRead, NULL )
|
||
|
||
|
||
|
sizeof(loginfo) != cbRead )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't read loginfo") ));
|
||
|
TrkRaiseLastError();
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("\nLog Header:\n") );
|
||
|
_tprintf( TEXT(" guidSignature = \t%s\n"), static_cast<const TCHAR*>(CStringize(logheader.guidSignature)) );
|
||
|
_tprintf( TEXT(" dwFormat = \t\t0x%x,0x%x\n"), logheader.dwFormat>>16, logheader.dwFormat&0xFFFF );
|
||
|
_tprintf( TEXT(" ProperShutdown = \t%s\n"), (logheader.dwFlags & PROPER_SHUTDOWN) ? TEXT("True") : TEXT("False") );
|
||
|
_tprintf( TEXT(" DownlevelDirtied = \t%s\n"), (logheader.dwFlags & DOWNLEVEL_DIRTIED) ? TEXT("True") : TEXT("False") );
|
||
|
_tprintf( TEXT(" Expansion start = \t%d\n"), logheader.expand.ilogStart );
|
||
|
_tprintf( TEXT(" end = \t%d\n"), logheader.expand.ilogEnd );
|
||
|
_tprintf( TEXT(" cb = \t%d\n"), logheader.expand.cbFile );
|
||
|
|
||
|
|
||
|
_tprintf( TEXT("\nLog Information:\n") );
|
||
|
_tprintf( TEXT(" Start = \t\t%lu\n"), loginfo.ilogStart );
|
||
|
_tprintf( TEXT(" End = \t\t%lu\n"), loginfo.ilogEnd );
|
||
|
_tprintf( TEXT(" Write = \t\t%lu\n"), loginfo.ilogWrite );
|
||
|
_tprintf( TEXT(" Read = \t\t%lu\n"), loginfo.ilogRead );
|
||
|
_tprintf( TEXT(" Last = \t\t%lu\n"), loginfo.ilogLast );
|
||
|
_tprintf( TEXT(" seqNext = \t\t%li\n"), loginfo.seqNext );
|
||
|
_tprintf( TEXT(" seqLastRead = \t%li\n"), loginfo.seqLastRead );
|
||
|
|
||
|
|
||
|
CVolumeId volidNTFS;
|
||
|
status = QueryVolumeId( iVol, &volidNTFS );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't get NTFS volume ID") ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("\nVolume Information:\n") );
|
||
|
_tprintf( TEXT(" Machine = \t\t%s\n"), static_cast<const TCHAR*>(CStringize(volinfo.machine)) );
|
||
|
_tprintf( TEXT(" VolId (log) = \t%s\n"), static_cast<const TCHAR*>(CStringize(volinfo.volid)) );
|
||
|
_tprintf( TEXT(" VolId (NTFS) = \t%s\n"), static_cast<const TCHAR*>(CStringize(volidNTFS)) );
|
||
|
_tprintf( TEXT(" Secret = \t\t%s\n"), static_cast<const TCHAR*>(CStringize(volinfo.secret)) );
|
||
|
_tprintf( TEXT(" Last Refresh = \t%d\n"), volinfo.cftLastRefresh.LowDateTime() );
|
||
|
_tprintf( TEXT(" Enter not-owned = \t%s\n"), volinfo.cftEnterNotOwned == CFILETIME(0)
|
||
|
? TEXT("(N/A)")
|
||
|
: static_cast<const TCHAR*>(CStringize(volinfo.cftEnterNotOwned)) );
|
||
|
_tprintf( TEXT(" Make OIDs reborn = \t%s\n"), volinfo.fDoMakeAllOidsReborn ? TEXT("True") : TEXT("False") );
|
||
|
_tprintf( TEXT(" Not-Created = \t%s\n"), volinfo.fNotCreated ? TEXT("True") : TEXT("False") );
|
||
|
|
||
|
if( NULL != hFile )
|
||
|
NtClose( hFile );
|
||
|
|
||
|
return( volinfo.volid );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
DisplayDcStatus( const CVolumeId &volid )
|
||
|
{
|
||
|
CRpcClientBinding rc;
|
||
|
TRKSVR_SYNC_VOLUME SyncVolume;
|
||
|
TRKSVR_MESSAGE_UNION Msg;
|
||
|
CMachineId mcidLocal( MCID_LOCAL );
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
rc.RcInitialize( mcidLocal, s_tszTrkWksLocalRpcProtocol, s_tszTrkWksLocalRpcEndPoint, NO_AUTHENTICATION );
|
||
|
|
||
|
printf( "\nDC Information:\n" );
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
Msg.MessageType = SYNC_VOLUMES;
|
||
|
Msg.ptszMachineID = NULL;
|
||
|
Msg.Priority = PRI_9;
|
||
|
Msg.SyncVolumes.cVolumes = 1;
|
||
|
Msg.SyncVolumes.pVolumes = &SyncVolume;
|
||
|
SyncVolume.hr = S_OK;
|
||
|
SyncVolume.SyncType = QUERY_VOLUME;
|
||
|
SyncVolume.volume = volid;
|
||
|
|
||
|
hr = LnkCallSvrMessage( rc, &Msg );
|
||
|
}
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(GetExceptionCode());
|
||
|
}
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
printf( " Couldn't get status from DC: %08x\n", hr );
|
||
|
|
||
|
if( HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hr )
|
||
|
printf( " Make sure you have the 0x1 bit set in the TestFlags registry value\n" );
|
||
|
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
if( TRK_S_VOLUME_NOT_FOUND == SyncVolume.hr )
|
||
|
{
|
||
|
printf( " Volume is not in DC\n" );
|
||
|
}
|
||
|
else if( TRK_S_VOLUME_NOT_OWNED == SyncVolume.hr )
|
||
|
{
|
||
|
printf( " Volume is not owned by this machine\n" );
|
||
|
}
|
||
|
else if( S_OK == SyncVolume.hr )
|
||
|
{
|
||
|
_tprintf( TEXT(" Sequence # = \t%li\n"), SyncVolume.seq );
|
||
|
_tprintf( TEXT(" Last Refresh = \t%lu\n"), SyncVolume.ftLastRefresh.dwLowDateTime );
|
||
|
//static_cast<const TCHAR*>(CStringize(CFILETIME(SyncVolume.ftLastRefresh))) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf( " Volume state couldn't get queried from DC: %08x\n", hr );
|
||
|
}
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
DisplayOidInformation( LONG iVol )
|
||
|
{
|
||
|
|
||
|
CObjId objid;
|
||
|
CDomainRelativeObjId droid;
|
||
|
CObjIdEnumerator oie;
|
||
|
|
||
|
ULONG cFilesWithOid = 0;
|
||
|
ULONG cCrossVolumeBitSet = 0;
|
||
|
|
||
|
if(oie.Initialize(CVolumeDeviceName(iVol)) == TRUE)
|
||
|
{
|
||
|
if(oie.FindFirst(&objid, &droid))
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
cFilesWithOid++;
|
||
|
|
||
|
if( droid.GetVolumeId().GetUserBitState() )
|
||
|
cCrossVolumeBitSet++;
|
||
|
|
||
|
} while(oie.FindNext(&objid, &droid));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf( "\nObjectID Information\n" );
|
||
|
printf( " Files with ObjectIDs = \t\t%lu\n", cFilesWithOid );
|
||
|
printf( " Files with x-volume bit set = \t%lu\n", cCrossVolumeBitSet );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
VolumeStatistics( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
NTSTATUS status = 0;
|
||
|
TCHAR tszFile[ MAX_PATH + 1 ];
|
||
|
TCHAR tszDir[ MAX_PATH + 1 ];
|
||
|
TCHAR* ptcTmp = NULL;
|
||
|
BOOL fSuccess = FALSE;
|
||
|
LONG iVol = 0;
|
||
|
|
||
|
*pcEaten = 0;
|
||
|
|
||
|
if( 1 > cArgs || IsHelpArgument(rgptszArgs[0]) )
|
||
|
{
|
||
|
printf( "\nOption VolStat\n"
|
||
|
" Purpose: Get link tracking info about a volume\n"
|
||
|
" Usage: -volstat <drive letter>\n"
|
||
|
" E.g.: -volstat D:\n" );
|
||
|
*pcEaten = 1;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
if( TEXT('a') > rgptszArgs[0][0]
|
||
|
&&
|
||
|
TEXT('z') < rgptszArgs[0][0]
|
||
|
&&
|
||
|
TEXT('A') > rgptszArgs[0][0]
|
||
|
&&
|
||
|
TEXT('Z') < rgptszArgs[0][0]
|
||
|
||
|
||
|
TEXT(':') != rgptszArgs[0][1] )
|
||
|
{
|
||
|
printf( "Parameter error. Use -? for usage info\n" );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
iVol = (LONG)((ULONG_PTR)CharLower((LPTSTR)rgptszArgs[0][0]) - TEXT('a'));
|
||
|
|
||
|
if( !IsLocalObjectVolume( iVol ))
|
||
|
{
|
||
|
_tprintf( TEXT("%c: isn't a local NTFS5 volume\n"), VolChar(iVol) );
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
CVolumeId volid;
|
||
|
|
||
|
EnablePrivilege( SE_RESTORE_NAME );
|
||
|
|
||
|
volid = DisplayLogStatus(iVol);
|
||
|
DisplayDcStatus( volid );
|
||
|
DisplayOidInformation( iVol );
|
||
|
|
||
|
fSuccess = TRUE;
|
||
|
}
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
||
|
{
|
||
|
printf( "Fatal error: %08x\n", GetExceptionCode() );
|
||
|
}
|
||
|
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
return( fSuccess );
|
||
|
|
||
|
} // main()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
VolumeIdSetOrGet( ULONG cArgs, TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
NTSTATUS status = STATUS_SUCCESS;
|
||
|
|
||
|
TCHAR tszFile[ MAX_PATH + 1 ];
|
||
|
WCHAR wszFile[ MAX_PATH + 1 ];
|
||
|
TCHAR tszUNCPath[ MAX_PATH + 1 ];
|
||
|
WCHAR wszOID[ CCH_GUID_STRING + 1 ];
|
||
|
ULONG cbInBuffer;
|
||
|
TCHAR tszMachineName[ MAX_PATH + 1 ];
|
||
|
LPCTSTR tszVolumePath = NULL;
|
||
|
USHORT iVolume;
|
||
|
|
||
|
OLECHAR oszOID[ CCH_GUID_STRING + 1 ];
|
||
|
|
||
|
if( 1 == cArgs && IsHelpArgument( rgptszArgs[0] ))
|
||
|
{
|
||
|
printf( "\nOption VolId\n"
|
||
|
" Purpose: Set or get volume IDs\n"
|
||
|
" Usage: -volid [-s <drive>: {GUID} | -g <drive>:]\n"
|
||
|
" Where: '-s' means Set, and '-g' means Get\n"
|
||
|
" E.g.: -volid -g d:\n"
|
||
|
" -volid -s d: {d2a2ac27-b89a-11d2-9335-00805ffe11b8}\n" );
|
||
|
// The volid in this example is actually the well-known invalid volid
|
||
|
*pcEaten = 1;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
else
|
||
|
if( 2 > cArgs
|
||
|
||
|
||
|
TEXT('-') != rgptszArgs[0][0]
|
||
|
&&
|
||
|
TEXT('/') != rgptszArgs[0][0]
|
||
|
||
|
||
|
TEXT(':') != rgptszArgs[1][1] )
|
||
|
{
|
||
|
printf( "Invalid parameter. Use -? for help\n" );
|
||
|
*pcEaten = 0;
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
*pcEaten = 2;
|
||
|
__try
|
||
|
{
|
||
|
CVolumeId volid;
|
||
|
|
||
|
TCHAR tcCommand = (TCHAR)CharUpper( (LPTSTR) rgptszArgs[0][1] );
|
||
|
TCHAR tcDrive = (TCHAR)CharUpper( (LPTSTR) rgptszArgs[1][0] );
|
||
|
LONG iVol = tcDrive - TEXT('A');
|
||
|
|
||
|
|
||
|
if( TEXT('G') == tcCommand )
|
||
|
{
|
||
|
OLECHAR *poszVolId;
|
||
|
|
||
|
status = QueryVolumeId( iVol, &volid );
|
||
|
if( FAILED(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't query for volume id") ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
|
||
|
hr = StringFromCLSID( *(GUID*)&volid, &poszVolId );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Failed StringFromClsid %08x"), hr ));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("VolID = %s\n"), poszVolId );
|
||
|
CoTaskMemFree( poszVolId );
|
||
|
|
||
|
}
|
||
|
else if( TEXT('S') == tcCommand && 3 <= cArgs )
|
||
|
{
|
||
|
TSZ2CLSID( rgptszArgs[2], (GUID*)&volid );
|
||
|
EnablePrivilege( SE_RESTORE_NAME );
|
||
|
status = SetVolId( iVol, volid );
|
||
|
if( FAILED(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't set volume id") ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf( "Invalid parameter. Use -? for help\n" );
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
printf( "Failed: hr = %08x\n", hr );
|
||
|
return( SUCCEEDED(hr) );
|
||
|
|
||
|
} // main()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DltAdminVolInfoFile( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
HRESULT hr;
|
||
|
HANDLE hFile = NULL;
|
||
|
IO_STATUS_BLOCK Iosb;
|
||
|
OLECHAR *poszVolId = NULL;
|
||
|
|
||
|
BYTE rgb[ 2 * MAX_PATH ];
|
||
|
PFILE_FS_VOLUME_INFORMATION pfile_fs_volume_information
|
||
|
= reinterpret_cast<PFILE_FS_VOLUME_INFORMATION>(rgb);
|
||
|
PFILE_FS_ATTRIBUTE_INFORMATION pfile_fs_attribute_information
|
||
|
= reinterpret_cast<PFILE_FS_ATTRIBUTE_INFORMATION>(rgb);
|
||
|
PFILE_FS_OBJECTID_INFORMATION pfile_fs_objectid_information
|
||
|
= reinterpret_cast<PFILE_FS_OBJECTID_INFORMATION>(rgb);
|
||
|
|
||
|
FILE_FS_SIZE_INFORMATION file_fs_size_information;
|
||
|
FILE_FS_FULL_SIZE_INFORMATION file_fs_full_size_information;
|
||
|
FILE_FS_DEVICE_INFORMATION file_fs_device_information;
|
||
|
|
||
|
TCHAR tszFileSystemAttributes[ 2 * MAX_PATH ];
|
||
|
DWORD dwFileSystemAttributeMask;
|
||
|
TCHAR *ptszDeviceType = NULL;
|
||
|
|
||
|
if( 0 == cArgs )
|
||
|
{
|
||
|
printf( "Missing parameter: a file/directory name must be specified\n" );
|
||
|
*pcEaten = 0;
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
if( IsHelpArgument( rgptszArgs[0] ))
|
||
|
{
|
||
|
printf( "\nOption VolInfoFile\n"
|
||
|
" Purpose: Get volume information, given a file or directory name\n"
|
||
|
" Usage: -volinfofile <file or directory>\n"
|
||
|
" E.g. -volinfofile C:\\foo.doc\n"
|
||
|
" -volinfofile \\\\scratch\\scratch\\jdoe\n" );
|
||
|
*pcEaten = 1;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
*pcEaten = 1;
|
||
|
|
||
|
TCHAR tszFileTime[ 80 ];
|
||
|
|
||
|
status = TrkCreateFile(
|
||
|
rgptszArgs[0],
|
||
|
FILE_READ_ATTRIBUTES,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||
|
FILE_OPEN,
|
||
|
FILE_SYNCHRONOUS_IO_NONALERT,
|
||
|
NULL,
|
||
|
&hFile );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't open file \"%s\" (%08x)"), rgptszArgs[1], status ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb,
|
||
|
pfile_fs_volume_information,
|
||
|
sizeof(rgb),
|
||
|
FileFsVolumeInformation );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't query volume information (%08x)"), status ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
|
||
|
pfile_fs_volume_information->VolumeLabel[ pfile_fs_volume_information->VolumeLabelLength/sizeof(WCHAR) ]
|
||
|
= L'\0';
|
||
|
|
||
|
static_cast<CFILETIME>(pfile_fs_volume_information->VolumeCreationTime)
|
||
|
.Stringize( ELEMENTS(tszFileTime), tszFileTime );
|
||
|
|
||
|
_tprintf( TEXT("\n")
|
||
|
TEXT("Volume creation time:\t%08x:%08x (%s)\n")
|
||
|
TEXT("Volume serial number:\t%08x\n")
|
||
|
TEXT("Supports objects:\t%s\n")
|
||
|
TEXT("Volume label:\t\t%s\n"),
|
||
|
pfile_fs_volume_information->VolumeCreationTime.HighPart,
|
||
|
pfile_fs_volume_information->VolumeCreationTime.LowPart,
|
||
|
tszFileTime,
|
||
|
pfile_fs_volume_information->VolumeSerialNumber,
|
||
|
pfile_fs_volume_information->SupportsObjects ? TEXT("True") : TEXT("False"),
|
||
|
pfile_fs_volume_information->VolumeLabel );
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb,
|
||
|
pfile_fs_attribute_information,
|
||
|
sizeof(rgb),
|
||
|
FileFsAttributeInformation );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't query attribute information (%08x)"), status ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
|
||
|
pfile_fs_attribute_information->FileSystemName[ pfile_fs_attribute_information->FileSystemNameLength/sizeof(WCHAR) ]
|
||
|
= L'\0';
|
||
|
|
||
|
_tcscpy( tszFileSystemAttributes, TEXT("") );
|
||
|
|
||
|
dwFileSystemAttributeMask = FILE_CASE_SENSITIVE_SEARCH
|
||
|
| FILE_CASE_PRESERVED_NAMES
|
||
|
| FILE_UNICODE_ON_DISK
|
||
|
| FILE_PERSISTENT_ACLS
|
||
|
| FILE_FILE_COMPRESSION
|
||
|
| FILE_VOLUME_QUOTAS
|
||
|
| FILE_SUPPORTS_SPARSE_FILES
|
||
|
| FILE_SUPPORTS_REPARSE_POINTS
|
||
|
| FILE_SUPPORTS_REMOTE_STORAGE
|
||
|
| FILE_VOLUME_IS_COMPRESSED
|
||
|
| FILE_SUPPORTS_OBJECT_IDS
|
||
|
| FILE_SUPPORTS_ENCRYPTION;
|
||
|
|
||
|
if( FILE_CASE_SENSITIVE_SEARCH & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tCase sensitive search\n"));
|
||
|
if( FILE_CASE_PRESERVED_NAMES & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tCase preserved names\n"));
|
||
|
if( FILE_UNICODE_ON_DISK & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tUnicode on disk\n"));
|
||
|
if( FILE_PERSISTENT_ACLS & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tPersistent ACLs\n"));
|
||
|
if( FILE_FILE_COMPRESSION & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tFile compression\n"));
|
||
|
if( FILE_VOLUME_QUOTAS & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tVolume quotas\n"));
|
||
|
if( FILE_SUPPORTS_SPARSE_FILES & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tSupports sparse files\n"));
|
||
|
if( FILE_SUPPORTS_REPARSE_POINTS & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tSupports reparse points\n"));
|
||
|
if( FILE_SUPPORTS_REMOTE_STORAGE & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tSupports remote storage\n"));
|
||
|
if( FILE_VOLUME_IS_COMPRESSED & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tVolume is compressed\n"));
|
||
|
if( FILE_SUPPORTS_OBJECT_IDS & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tSupports object IDs\n"));
|
||
|
if( FILE_SUPPORTS_ENCRYPTION & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tSupports encryption\n"));
|
||
|
if( FILE_NAMED_STREAMS & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\tSupports named streams\n"));
|
||
|
if( !dwFileSystemAttributeMask & pfile_fs_attribute_information->FileSystemAttributes )
|
||
|
_tcscat( tszFileSystemAttributes, TEXT("\t\t\t(Unknown bit)"));
|
||
|
|
||
|
|
||
|
_tprintf( TEXT("File system attributes:\t%08x\n%s")
|
||
|
TEXT("Max component name:\t%d\n")
|
||
|
TEXT("File system name\t%s\n"),
|
||
|
pfile_fs_attribute_information->FileSystemAttributes, tszFileSystemAttributes,
|
||
|
pfile_fs_attribute_information->MaximumComponentNameLength,
|
||
|
pfile_fs_attribute_information->FileSystemName );
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb,
|
||
|
pfile_fs_objectid_information,
|
||
|
sizeof(rgb),
|
||
|
FileFsObjectIdInformation );
|
||
|
if( NT_SUCCESS(status) )
|
||
|
{
|
||
|
hr = StringFromCLSID( *(GUID*)pfile_fs_objectid_information->ObjectId, &poszVolId );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Failed StringFromClsid %08x"), hr ));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("Volume Id:\t\t%s\n"), poszVolId );
|
||
|
CoTaskMemFree( poszVolId );
|
||
|
}
|
||
|
else if( status != STATUS_INVALID_PARAMETER && status != STATUS_OBJECT_NAME_NOT_FOUND )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't query objectid information (%08x)"), status ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb,
|
||
|
&file_fs_full_size_information,
|
||
|
sizeof(file_fs_full_size_information),
|
||
|
FileFsFullSizeInformation );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb,
|
||
|
&file_fs_size_information,
|
||
|
sizeof(file_fs_size_information),
|
||
|
FileFsSizeInformation );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't query full size info or size info (%08x)"), status ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
|
||
|
double TotalAllocInMB = file_fs_size_information.TotalAllocationUnits.QuadPart
|
||
|
*
|
||
|
file_fs_size_information.SectorsPerAllocationUnit
|
||
|
*
|
||
|
file_fs_size_information.BytesPerSector
|
||
|
/
|
||
|
1000000.0;
|
||
|
|
||
|
_tprintf( TEXT("Total allocation units:\t%I64u (%.2fMB)\n")
|
||
|
TEXT("Available alloc:\t%I64u units\n")
|
||
|
TEXT("Sectors per alloc unit:\t%d\n")
|
||
|
TEXT("Bytes per sector:\t%d\n"),
|
||
|
file_fs_size_information.TotalAllocationUnits.QuadPart,
|
||
|
TotalAllocInMB,
|
||
|
file_fs_size_information.AvailableAllocationUnits.QuadPart,
|
||
|
file_fs_size_information.SectorsPerAllocationUnit,
|
||
|
file_fs_size_information.BytesPerSector );
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
double TotalAllocInMB = file_fs_full_size_information.TotalAllocationUnits.QuadPart
|
||
|
*
|
||
|
file_fs_full_size_information.SectorsPerAllocationUnit
|
||
|
*
|
||
|
file_fs_full_size_information.BytesPerSector
|
||
|
/
|
||
|
1000000.0;
|
||
|
|
||
|
double CallerAvailAllocInMB
|
||
|
= file_fs_full_size_information.CallerAvailableAllocationUnits.QuadPart
|
||
|
*
|
||
|
file_fs_full_size_information.SectorsPerAllocationUnit
|
||
|
*
|
||
|
file_fs_full_size_information.BytesPerSector
|
||
|
/
|
||
|
1000000.0;
|
||
|
|
||
|
double ActualAvailAllocInMB
|
||
|
= file_fs_full_size_information.ActualAvailableAllocationUnits.QuadPart
|
||
|
*
|
||
|
file_fs_full_size_information.SectorsPerAllocationUnit
|
||
|
*
|
||
|
file_fs_full_size_information.BytesPerSector
|
||
|
/
|
||
|
1000000.0;
|
||
|
|
||
|
_tprintf( TEXT("Total allocation units:\t%I64u (%.2fMB)\n")
|
||
|
TEXT("Caller avail alloc:\t%I64u units (%.2fMB)\n")
|
||
|
TEXT("Actual avail alloc:\t%I64u units (%.2fMB)\n")
|
||
|
TEXT("Sectors per alloc unit:\t%d\n")
|
||
|
TEXT("Bytes per sector:\t%d\n"),
|
||
|
file_fs_full_size_information.TotalAllocationUnits.QuadPart,
|
||
|
TotalAllocInMB,
|
||
|
file_fs_full_size_information.CallerAvailableAllocationUnits.QuadPart,
|
||
|
CallerAvailAllocInMB,
|
||
|
file_fs_full_size_information.ActualAvailableAllocationUnits.QuadPart,
|
||
|
ActualAvailAllocInMB,
|
||
|
file_fs_full_size_information.SectorsPerAllocationUnit,
|
||
|
file_fs_full_size_information.BytesPerSector );
|
||
|
}
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb,
|
||
|
&file_fs_device_information,
|
||
|
sizeof(file_fs_device_information),
|
||
|
FileFsDeviceInformation );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't query file fs device information (%08x)"), status ));
|
||
|
TrkRaiseNtStatus(status);
|
||
|
}
|
||
|
|
||
|
switch( file_fs_device_information.DeviceType )
|
||
|
{
|
||
|
case FILE_DEVICE_NETWORK:
|
||
|
ptszDeviceType = L"Network"; break;
|
||
|
case FILE_DEVICE_NETWORK_FILE_SYSTEM:
|
||
|
ptszDeviceType = L"Network file system"; break;
|
||
|
case FILE_DEVICE_CD_ROM:
|
||
|
ptszDeviceType = L"CDROM"; break;
|
||
|
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
|
||
|
ptszDeviceType = L"CDROM file system"; break;
|
||
|
case FILE_DEVICE_VIRTUAL_DISK:
|
||
|
ptszDeviceType = L"Virtual disk"; break;
|
||
|
case FILE_DEVICE_DISK:
|
||
|
ptszDeviceType = file_fs_device_information.Characteristics & FILE_REMOVABLE_MEDIA
|
||
|
? L"Removable disk" : L"Fixed disk";
|
||
|
break;
|
||
|
case FILE_DEVICE_DISK_FILE_SYSTEM:
|
||
|
ptszDeviceType = file_fs_device_information.Characteristics & FILE_REMOVABLE_MEDIA
|
||
|
? L"Removable disk file system" : L"Fixed disk file system";
|
||
|
break;
|
||
|
default:
|
||
|
ptszDeviceType = L"Unknown";
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("Device Type:\t\t%s%s\n"),
|
||
|
ptszDeviceType,
|
||
|
(file_fs_device_information.Characteristics & FILE_REMOTE_DEVICE)
|
||
|
? TEXT(" (remote)")
|
||
|
: TEXT("")
|
||
|
);
|
||
|
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
}
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
||
|
{
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
if( NULL != hFile )
|
||
|
NtClose( hFile );
|
||
|
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
printf( "Failed: hr = %08x\n", hr );
|
||
|
return SUCCEEDED(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DeleteIdFromVolumeTable( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
CVolumeId volid;
|
||
|
CStringize stringize;
|
||
|
CRpcClientBinding rc;
|
||
|
TRKSVR_SYNC_VOLUME SyncVolume;
|
||
|
TRKSVR_MESSAGE_UNION Msg;
|
||
|
CMachineId mcidLocal( MCID_LOCAL );
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if( 0 == cArgs )
|
||
|
{
|
||
|
printf( "Missing parameter: a volume ID name must be specified\n"
|
||
|
"(in \"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\" form)\n" );
|
||
|
*pcEaten = 0;
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("Deleting volume %s from DC volume table\n"), rgptszArgs[0] );
|
||
|
|
||
|
if( IsHelpArgument( rgptszArgs[0] ))
|
||
|
{
|
||
|
printf( "\nOption DelDcVolId\n"
|
||
|
" Purpose: Delete a volume ID from the DC volume table\n"
|
||
|
" Usage: -deldcvolid <stringized volume ID>\n"
|
||
|
" E.g. -deldcvolid {56730825-3ddc-11d2-a168-00805ffe11b8}\n"
|
||
|
" Note: The volume ID must be owned by this machine.\n"
|
||
|
" Also, the services\\trkwks\\parameters\\configuration\\trkflags\n"
|
||
|
" reg value must have the 0x1 bit set.\n" );
|
||
|
*pcEaten = 1;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
*pcEaten = 1;
|
||
|
|
||
|
// Convert the volid string to a volid
|
||
|
|
||
|
stringize.Use( rgptszArgs[0] );
|
||
|
volid = stringize;
|
||
|
|
||
|
if( CVolumeId() == volid )
|
||
|
{
|
||
|
_tprintf( TEXT("Error: Invalid volume ID\n") );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
// Send the delete request
|
||
|
|
||
|
rc.RcInitialize( mcidLocal, s_tszTrkWksLocalRpcProtocol, s_tszTrkWksLocalRpcEndPoint, NO_AUTHENTICATION );
|
||
|
__try
|
||
|
{
|
||
|
Msg.MessageType = SYNC_VOLUMES;
|
||
|
Msg.ptszMachineID = NULL;
|
||
|
Msg.Priority = PRI_9;
|
||
|
Msg.SyncVolumes.cVolumes = 1;
|
||
|
Msg.SyncVolumes.pVolumes = &SyncVolume;
|
||
|
SyncVolume.hr = S_OK;
|
||
|
SyncVolume.SyncType = DELETE_VOLUME;
|
||
|
SyncVolume.volume = volid;
|
||
|
|
||
|
hr = LnkCallSvrMessage( rc, &Msg );
|
||
|
}
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
|
||
|
if( SUCCEEDED(hr) )
|
||
|
hr = SyncVolume.hr;
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
_tprintf( TEXT("Error: %08x\n"), hr );
|
||
|
else if( S_OK != hr )
|
||
|
_tprintf( TEXT("Success code: %08x\n"), hr );
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
printf( "Failed: hr = %08x\n", hr );
|
||
|
return( SUCCEEDED(hr) );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DeleteIdFromMoveTable( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
CDomainRelativeObjId droid;
|
||
|
CStringize stringize;
|
||
|
CRpcClientBinding rc;
|
||
|
TRKSVR_MESSAGE_UNION Msg;
|
||
|
CMachineId mcidLocal( MCID_LOCAL );
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if( 0 == cArgs )
|
||
|
{
|
||
|
printf( "Missing parameter: a birth ID name must be specified\n"
|
||
|
"(in \"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\" form)\n" );
|
||
|
*pcEaten = 0;
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("Deleting file %s from DC move table\n"), rgptszArgs[0] );
|
||
|
|
||
|
if( IsHelpArgument( rgptszArgs[0] ))
|
||
|
{
|
||
|
printf( "\nOption DelDcMoveId\n"
|
||
|
" Purpose: Delete an entry from the DC move table\n"
|
||
|
" Usage: -deldcmoveid <stringized GUIDs of birth ID>\n"
|
||
|
" E.g. -deldcmoveid {xxx...xxx}{xxx...xxx}\n"
|
||
|
" Where: a stringized GUID is e.g. \"{56730825-3ddc-11d2-a168-00805ffe11b8}\"\n"
|
||
|
" Note: The birth ID must be owned by this machine.\n"
|
||
|
" Also, the services\\trkwks\\parameters\\configuration\\trkflags\n"
|
||
|
" reg value must have the 0x1 bit set.\n" );
|
||
|
*pcEaten = 1;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
*pcEaten = 1;
|
||
|
|
||
|
stringize.Use( rgptszArgs[0] );
|
||
|
droid = stringize;
|
||
|
|
||
|
if( CDomainRelativeObjId() == droid )
|
||
|
{
|
||
|
_tprintf( TEXT("Error: Invalid birth ID\n") );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
|
||
|
rc.RcInitialize( mcidLocal, s_tszTrkWksLocalRpcProtocol, s_tszTrkWksLocalRpcEndPoint, NO_AUTHENTICATION );
|
||
|
__try
|
||
|
{
|
||
|
CVolumeId volidDummy;
|
||
|
Msg.MessageType = DELETE_NOTIFY;
|
||
|
Msg.ptszMachineID = NULL;
|
||
|
Msg.Priority = PRI_5;
|
||
|
Msg.Delete.cVolumes = 0;
|
||
|
Msg.Delete.pVolumes = &volidDummy;
|
||
|
|
||
|
Msg.Delete.adroidBirth = &droid;
|
||
|
Msg.Delete.cdroidBirth = 1;
|
||
|
|
||
|
LnkCallSvrMessage(rc, &Msg);
|
||
|
}
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(GetExceptionCode());
|
||
|
}
|
||
|
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
_tprintf( TEXT("Error: %08x\n"), hr );
|
||
|
else if( S_OK != hr )
|
||
|
_tprintf( TEXT("Success code: %x\n"), hr );
|
||
|
|
||
|
return( SUCCEEDED(hr) );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DltAdminLookupVolId( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
CVolumeId volid;
|
||
|
CStringize stringize;
|
||
|
CRpcClientBinding rc;
|
||
|
TRKSVR_SYNC_VOLUME SyncVolume;
|
||
|
TRKSVR_MESSAGE_UNION Msg;
|
||
|
CMachineId mcidLocal( MCID_LOCAL );
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if( 0 == cArgs )
|
||
|
{
|
||
|
printf( "Missing parameter: a volume ID name must be specified\n"
|
||
|
"(in \"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\" form)\n" );
|
||
|
*pcEaten = 0;
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("Searching for volume %s in DC volume table\n"), rgptszArgs[0] );
|
||
|
|
||
|
if( IsHelpArgument( rgptszArgs[0] ))
|
||
|
{
|
||
|
printf( "\nOption LookupVolId\n"
|
||
|
" Purpose: Look up a volume ID from the DC volume table\n"
|
||
|
" Usage: -lookupvolid <stringized volume ID>\n"
|
||
|
" E.g. -lookupvolid {56730825-3ddc-11d2-a168-00805ffe11b8}\n"
|
||
|
" Note: The services\\trkwks\\parameters\\configuration\\trkflags\n"
|
||
|
" reg value must have the 0x1 bit set before trkwks is started.\n" );
|
||
|
*pcEaten = 1;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
*pcEaten = 1;
|
||
|
|
||
|
// Convert the volid string to a volid
|
||
|
|
||
|
stringize.Use( rgptszArgs[0] );
|
||
|
volid = stringize;
|
||
|
|
||
|
if( CVolumeId() == volid )
|
||
|
{
|
||
|
_tprintf( TEXT("Error: Invalid volume ID\n") );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
// Send the delete request
|
||
|
|
||
|
rc.RcInitialize( mcidLocal, s_tszTrkWksLocalRpcProtocol, s_tszTrkWksLocalRpcEndPoint, NO_AUTHENTICATION );
|
||
|
__try
|
||
|
{
|
||
|
Msg.MessageType = SYNC_VOLUMES;
|
||
|
Msg.ptszMachineID = NULL;
|
||
|
Msg.Priority = PRI_9;
|
||
|
Msg.SyncVolumes.cVolumes = 1;
|
||
|
Msg.SyncVolumes.pVolumes = &SyncVolume;
|
||
|
SyncVolume.hr = S_OK;
|
||
|
SyncVolume.SyncType = FIND_VOLUME;
|
||
|
SyncVolume.volume = volid;
|
||
|
|
||
|
hr = LnkCallSvrMessage( rc, &Msg );
|
||
|
}
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||
|
}
|
||
|
|
||
|
if( SUCCEEDED(hr) )
|
||
|
hr = SyncVolume.hr;
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
_tprintf( TEXT("Error: %08x\n"), hr );
|
||
|
else
|
||
|
{
|
||
|
if( S_OK != hr )
|
||
|
_tprintf( TEXT("Success code is %08x\n"), hr );
|
||
|
|
||
|
_tprintf( TEXT("Machine = \"%s\"\n"), static_cast<const TCHAR*>(CStringize(SyncVolume.machine)) );
|
||
|
}
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
printf( "Failed: hr = %08x\n", hr );
|
||
|
return( SUCCEEDED(hr) );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DltAdminLookupDroid( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten )
|
||
|
{
|
||
|
CVolumeId volid;
|
||
|
CStringize stringize;
|
||
|
CRpcClientBinding rc;
|
||
|
TRK_FILE_TRACKING_INFORMATION FileTrackingInformation;
|
||
|
TRKSVR_MESSAGE_UNION Msg;
|
||
|
CDomainRelativeObjId droid;
|
||
|
CMachineId mcidLocal( MCID_LOCAL );
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if( 0 == cArgs )
|
||
|
{
|
||
|
printf( "Missing parameter: a DROID must be specified\n"
|
||
|
"(in \"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\" form)\n" );
|
||
|
*pcEaten = 0;
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
_tprintf( TEXT("Searching for move ID %s in DC volume table\n"), rgptszArgs[0] );
|
||
|
|
||
|
if( IsHelpArgument( rgptszArgs[0] ))
|
||
|
{
|
||
|
printf( "\nOption LookupDroid\n"
|
||
|
" Purpose: Look up a DROID from the DC move table\n"
|
||
|
" Usage: -lookupdroid <stringized DROIID>\n"
|
||
|
" E.g. -lookupdroid {f8b534f0-b65b-11d2-8fd8-0008c709d19e}{0ed45deb-03ed-11d3-b766-00805ffe11b8}\n"
|
||
|
" Note: You must be running as an administrator\n" );
|
||
|
*pcEaten = 1;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
*pcEaten = 1;
|
||
|
|
||
|
stringize.Use( rgptszArgs[0] );
|
||
|
droid = stringize;
|
||
|
|
||
|
if( CDomainRelativeObjId() == droid )
|
||
|
{
|
||
|
_tprintf( TEXT("Error: Invalid birth ID\n") );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
|
||
|
rc.RcInitialize( mcidLocal, s_tszTrkWksLocalRpcProtocol, s_tszTrkWksLocalRpcEndPoint, NO_AUTHENTICATION );
|
||
|
__try
|
||
|
{
|
||
|
memset( &FileTrackingInformation, 0, sizeof(FileTrackingInformation) );
|
||
|
FileTrackingInformation.droidLast = droid;
|
||
|
|
||
|
Msg.MessageType = SEARCH;
|
||
|
Msg.ptszMachineID = NULL;
|
||
|
Msg.Priority = PRI_5;
|
||
|
Msg.Search.cSearch = 1;
|
||
|
Msg.Search.pSearches = &FileTrackingInformation;
|
||
|
|
||
|
LnkCallSvrMessage(rc, &Msg);
|
||
|
}
|
||
|
__except( EXCEPTION_EXECUTE_HANDLER )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(GetExceptionCode());
|
||
|
}
|
||
|
|
||
|
|
||
|
if( SUCCEEDED(hr) )
|
||
|
hr = FileTrackingInformation.hr;
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
_tprintf( TEXT("Error: %08x\n"), hr );
|
||
|
else
|
||
|
{
|
||
|
if( S_OK != hr )
|
||
|
_tprintf( TEXT("Success code is %08x\n"), hr );
|
||
|
|
||
|
_tprintf( TEXT("Machine = \"%s\"\n"), static_cast<const TCHAR*>(CStringize(FileTrackingInformation.mcidLast)) );
|
||
|
}
|
||
|
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
EXTERN_C void __cdecl _tmain( int cArgs, TCHAR *prgtszArg[])
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
NTSTATUS status = STATUS_SUCCESS;
|
||
|
int iArg = 0;
|
||
|
int iError = 0;
|
||
|
|
||
|
OLECHAR oszOID[ CCH_GUID_STRING + 1 ];
|
||
|
|
||
|
TrkDebugCreate( TRK_DBG_FLAGS_WRITE_TO_DBG, "DltAdmin" );
|
||
|
hr = CoInitialize( NULL );
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
_tprintf( TEXT("Unable to CoInitialize( NULL )-- aborting. (0x%08x)\n"),
|
||
|
hr );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
TCHAR tszStringizedTime[ 80 ];
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
// Skip over the executable name
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( 0 == cArgs )
|
||
|
{
|
||
|
Usage();
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
for( ; iArg <= cArgs; cArgs--, iArg++ )
|
||
|
{
|
||
|
ULONG cEaten = 0;
|
||
|
|
||
|
if( TEXT('-') != prgtszArg[iArg][0]
|
||
|
&&
|
||
|
TEXT('/') != prgtszArg[iArg][0] )
|
||
|
{
|
||
|
_tprintf( TEXT("Invalid option, ignoring: %s\n"), prgtszArg[iArg] );
|
||
|
iError = max( iError, 1 );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if( !_tcsicmp( TEXT("deldcvolid"), &prgtszArg[iArg][1] ) )
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
if( !DeleteIdFromVolumeTable( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("deldcmoveid"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DeleteIdFromMoveTable( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("lookupvolid"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminLookupVolId( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("lookupdroid"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminLookupDroid( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("volinfofile"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminVolInfoFile( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("cleanvol"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminCleanVol( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("svrstat"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminSvrStat( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("volstat"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !VolumeStatistics( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("volid"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !VolumeIdSetOrGet( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("lockvol"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminLockVol( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("fileoid"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminFileOid( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("enumoids"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminEnumOids( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("oidsnap"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminOidSnap( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("link"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminLink( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("loadlib"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminProcessAction( LOAD_LIBRARY, cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("freelib"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminProcessAction( FREE_LIBRARY, cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("debugbreak"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminProcessAction( DEBUG_BREAK, cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("createprocess"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminProcessAction( CREATE_PROCESS, cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("config"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminConfig( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("refresh"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminRefresh( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("setvolseq"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminSetVolumeSeqNumber( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("setdroidseq"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminSetDroidSeqNumber( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("backupread"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminBackupRead( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("backupwrite"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
|
||
|
if( !DltAdminBackupWrite( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("sleep"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
iArg++;
|
||
|
cArgs--;
|
||
|
Sleep( 1000 );
|
||
|
}
|
||
|
else if( !_tcsicmp( TEXT("temp"), &prgtszArg[iArg][1] ))
|
||
|
{
|
||
|
if( !DltAdminTemp( cArgs, &prgtszArg[iArg], &cEaten ))
|
||
|
iError = max( iError, 2 );
|
||
|
iArg += cEaten;
|
||
|
cArgs -= cEaten;
|
||
|
}
|
||
|
else if( TEXT('?') == prgtszArg[iArg][1] )
|
||
|
{
|
||
|
Usage();
|
||
|
exit( 1 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_tprintf( TEXT("Invalid option, ignoring: %s\n"), prgtszArg[iArg] );
|
||
|
iError = max( iError, 1 );
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = GetExceptionCode();
|
||
|
iError = max( iError, 2 );
|
||
|
}
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
printf( "HR = %08X\n", hr );
|
||
|
|
||
|
CoUninitialize();
|
||
|
|
||
|
// return( iError );
|
||
|
|
||
|
} // main()
|
||
|
|