//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996. // //-------------------------------------------------------------------------- #include #pragma hdrstop #include #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(-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 :\n" " Where: 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(-1) == iVolume ) { printf( "Invalid parameter. Use -? for usage info\n" ); return( FALSE ); } tszVolume[4] += static_cast(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