|
|
#include <pch.cxx>
#pragma hdrstop
#include <ole2.h>
#include "trkwks.hxx"
#include "trksvr.hxx"
#include "dltadmin.hxx"
void CDomainRelativeObjId::FillLdapIdtKeyBuffer(TCHAR * const pchCN, DWORD cch) const { TCHAR *pchBuf = pchCN; _tcscpy(pchBuf, TEXT("CN=")); pchBuf = pchBuf + 3; _volume.Stringize(pchBuf); _object.Stringize(pchBuf); TrkAssert(pchBuf <= pchCN+cch); }
void ShowMoveCounter( const TCHAR *ptszHostName ) { CDbConnection dbc; dbc.Initialize( NULL, ptszHostName );
CTrkSvrConfiguration configSvr; configSvr.Initialize();
BOOL fSuccess = FALSE; struct berval** ppbvCounter = NULL; TCHAR* rgtszAttrs[2]; LDAPMessage* pRes = NULL; int ldapRV; int cEntries = 0; LDAPMessage* pEntry = NULL; CLdapQuotaCounterKeyDn dnKeyCounter(dbc.GetBaseDn()); DWORD dwCounter = 0;
__try { rgtszAttrs[0] = const_cast<TCHAR*>(s_volumeSecret); rgtszAttrs[1] = NULL; ldapRV = ldap_search_s(dbc.Ldap(), dnKeyCounter, LDAP_SCOPE_BASE, TEXT("(ObjectClass=*)"), rgtszAttrs, 0, &pRes); if( LDAP_NO_SUCH_OBJECT == ldapRV ) { printf( "Move table counter doesn't exist\n" ); __leave; } else if( LDAP_SUCCESS != ldapRV ) { printf( "Couldn't read move table counter (%d)\n", ldapRV ); __leave; }
cEntries = ldap_count_entries(dbc.Ldap(), pRes); if( 0 == cEntries ) { printf( "Move table counter didn't exist or couldn't be read\n" ); __leave; } else if( 1 != cEntries ) { printf( "Too many move table counters (%d)!\n", cEntries ); __leave; }
pEntry = ldap_first_entry(dbc.Ldap(), pRes); if(NULL == pEntry) { printf( "Entries couldn't be read from result\n" ); __leave; }
ppbvCounter = ldap_get_values_len(dbc.Ldap(), pEntry, const_cast<TCHAR*>(s_volumeSecret) ); if (ppbvCounter == NULL) { _tprintf( TEXT("Move table counter is corrupt, missing %s attribute\n"), s_volumeSecret ); __leave; }
if ((*ppbvCounter)->bv_len < sizeof(DWORD)) { _tprintf( TEXT("Move table counter attribute %s has wrong type (%d)\n"), s_volumeSecret, (*ppbvCounter)->bv_len ); __leave; }
memcpy( (PCHAR)&dwCounter, (*ppbvCounter)->bv_val, sizeof(DWORD) ); printf( "Move table counter (in DS) %lu\n", dwCounter ); } __finally { if(NULL != pRes) { ldap_msgfree(pRes); } if (ppbvCounter != NULL) { ldap_value_free_len(ppbvCounter); } }
}
/*
ShowDcEntries( const TCHAR *ptszHostName ) { TCHAR* rgptszAttrs[4]; LDAPMessage* pRes = NULL; int ldapRV; HRESULT hr = E_FAIL;
CDbConnection dbc; dbc.Initialize( NULL, ptszHostName );
CLdapVolumeKeyDn dnKey(dbc.GetBaseDn()); LONGLONG llCreationTime, llLastAliveTime; CFILETIME cftNow; CTrkSvrConfiguration configSvr; configSvr.Initialize();
struct berval ** ppbvMachineId = NULL; TCHAR** pptszCreationTime = NULL; TCHAR** pptszLastAliveTime = NULL; LDAPMessage * pEntry = NULL;
struct SDcEntries { CMachineId mcid; BOOL fSuspended; CFILETIME cftCreation; CFILETIME cftLastAlive; };
SDcEntries rgsDcEntries[ 100 ]; ULONG cDcEntries = 0; CMachineId mcidDesignated; ULONG cEntries = 0;
__try { rgptszAttrs[0] = const_cast<TCHAR*>(s_Cn); rgptszAttrs[1] = const_cast<TCHAR*>(s_timeVolChange); rgptszAttrs[2] = const_cast<TCHAR*>(s_timeRefresh); rgptszAttrs[3] = NULL;
ldapRV = ldap_search_s( dbc.Ldap(), dnKey, LDAP_SCOPE_ONELEVEL, TEXT("(cn=QTDC_*)"), rgptszAttrs, 0, &pRes); if(LDAP_SUCCESS != ldapRV) { printf( "Failed ldap_search_s (%lu)\n", LdapMapErrorToWin32(ldapRV) ); hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldapRV) ); __leave; }
cEntries = ldap_count_entries( dbc.Ldap(), pRes ); if(cEntries < 1) __leave;
pEntry = ldap_first_entry( dbc.Ldap(), pRes ); if(NULL == pEntry) { printf( "Invalid ldap_first_entry\n" ); __leave; }
// Loop through the results.
while(TRUE) { // Get the machine id.
ppbvMachineId = ldap_get_values_len( dbc.Ldap(), pEntry, const_cast<TCHAR*>(s_Cn) ); if(NULL == ppbvMachineId) { printf( "Couldn't get machine ID\n" ); hr = TRK_E_CORRUPT_VOLTAB; __leave; } if((*ppbvMachineId)->bv_val == NULL) { printf( "Couldn't get machine ID\n" ); hr = TRK_E_CORRUPT_VOLTAB; __leave; } memcpy( &rgsDcEntries[cDcEntries].mcid, (*ppbvMachineId)->bv_val + 5, strlen((*ppbvMachineId)->bv_val+5));
// Get the creation time.
pptszCreationTime = ldap_get_values(dbc.Ldap(), pEntry, const_cast<TCHAR*>(s_timeVolChange) ); if(NULL == pptszCreationTime) { printf( "Couldn't get the creation time\n" ); hr = TRK_E_CORRUPT_VOLTAB; __leave; } _stscanf(*pptszCreationTime, TEXT("%I64u"), &llCreationTime); rgsDcEntries[cDcEntries].cftCreation = CFILETIME(llCreationTime);
// Get the last alive time.
pptszLastAliveTime = ldap_get_values(dbc.Ldap(), pEntry, const_cast<TCHAR*>(s_timeRefresh) ); if(NULL == pptszLastAliveTime) { printf( "Couldn't get last alive time\n" ); hr = TRK_E_CORRUPT_VOLTAB; __leave; } _stscanf(*pptszLastAliveTime, TEXT("%I64u"), &llLastAliveTime); rgsDcEntries[cDcEntries].cftLastAlive = CFILETIME(llLastAliveTime);
rgsDcEntries[cDcEntries].fSuspended = FALSE; if(((LONGLONG)cftNow - (LONGLONG)rgsDcEntries[cDcEntries].cftCreation) / 10000000 < configSvr.GetDcSuspensionPeriod() || ((LONGLONG)cftNow - (LONGLONG)rgsDcEntries[cDcEntries].cftLastAlive) / 10000000 > configSvr.GetDcSuspensionPeriod() ) { rgsDcEntries[cDcEntries].fSuspended = TRUE; } else if( rgsDcEntries[cDcEntries].mcid > mcidDesignated ) { mcidDesignated = rgsDcEntries[cDcEntries].mcid; }
if (ppbvMachineId != NULL) { ldap_value_free_len(ppbvMachineId); ppbvMachineId = NULL; }
if (pptszCreationTime != NULL) { ldap_value_free(pptszCreationTime); pptszCreationTime = NULL; }
if (pptszLastAliveTime != NULL) { ldap_value_free(pptszLastAliveTime); pptszLastAliveTime = NULL; }
cDcEntries++; pEntry = ldap_next_entry(dbc.Ldap(), pEntry); if(!pEntry) { break; } } // while( TRUE )
for( int iEntry = 0; iEntry < cDcEntries; iEntry++ ) { CFILETIME cftLocal; TCHAR tszTime[ 80 ];
printf( " %-16s ", &rgsDcEntries[iEntry].mcid );
if( rgsDcEntries[iEntry].mcid == mcidDesignated ) printf( " (** Designated **)\n" ); else if( rgsDcEntries[iEntry].fSuspended ) printf(" (suspended)\n" ); else printf(" (not suspended)\n" );
cftLocal = rgsDcEntries[iEntry].cftCreation.ConvertUtcToLocal(); cftLocal.Stringize( ELEMENTS(tszTime), tszTime ); _tprintf( TEXT(" Create = %s\n"), tszTime );
cftLocal = rgsDcEntries[iEntry].cftLastAlive.ConvertUtcToLocal(); cftLocal.Stringize( ELEMENTS(tszTime), tszTime ); _tprintf( TEXT(" Alive = %s\n"), tszTime );
}
} __finally { if (ppbvMachineId != NULL) { ldap_value_free_len(ppbvMachineId); } if (pptszCreationTime != NULL) { ldap_value_free(pptszCreationTime); } if (pptszLastAliveTime != NULL) { ldap_value_free(pptszLastAliveTime); }
if( NULL != pRes ) ldap_msgfree(pRes); }
return hr; } */
BOOL DltAdminSvrStat( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten ) { NTSTATUS status; HRESULT hr = S_OK;;
RPC_BINDING_HANDLE BindingHandle; BOOL fBound = FALSE; BOOL fShowDsInfo = FALSE; ULONG iDcName = 0;
if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] )) { printf( "\nOption SvrStat\n" " Purpose: Query a DC for TrkSvr statistics\n" " Usage: -svrstat [options] <DC name>\n" " E.g.: -svrstat ntdsdc0\n" " Note: To find a DC name for a domain, use the nltest tool\n" ); *pcEaten = 1; return( TRUE ); }
_tprintf( TEXT("Checking for TrkSvr statistics\n"), rgptszArgs[0] );
if( 1 > cArgs ) { printf( "Invalid parameters. Use -? for usage info\n" ); *pcEaten = 0; return( FALSE ); }
*pcEaten = 1;
if( 2 <= cArgs && TEXT('-') == rgptszArgs[0][0] ) { if( TEXT('d') == rgptszArgs[0][1] || TEXT('D') == rgptszArgs[0][1] ) { fShowDsInfo = TRUE; } else { printf( "Invalid option. Use -? for help\n" ); return( FALSE ); }
iDcName = 1; (*pcEaten)++; }
__try { CFILETIME cftLocal(0); TCHAR tszLocalFileTime[ 80 ]; WCHAR wszAuthName[ 80 ]; WCHAR wszUser[ 80 ]; WCHAR wszDomain[ 80 ]; RPC_STATUS rpcstatus = RPC_S_OK; RPC_TCHAR * ptszStringBinding = NULL;
TRKSVR_MESSAGE_UNION Msg; memset( &Msg, 0, sizeof(Msg) ); Msg.MessageType = STATISTICS; Msg.Priority = PRI_0;
// Create a binding string
rpcstatus = RpcStringBindingCompose(NULL, L"ncacn_np", //L"ncacn_ip_tcp", //L"ncacn_np",
const_cast<TCHAR*>(rgptszArgs[iDcName]), L"\\pipe\\trkwks", //L"", //L"\\pipe\\trkwks",
NULL, &ptszStringBinding); if( RPC_S_OK != rpcstatus ) { hr = HRESULT_FROM_WIN32( rpcstatus ); _tprintf( TEXT("Failed RpcStringBindingCompose (%d)\n"), rpcstatus ); goto Exit; } _tprintf( TEXT("String binding = %s\n"), ptszStringBinding );
// Get a client binding handle.
rpcstatus = RpcBindingFromStringBinding(ptszStringBinding, &BindingHandle); RpcStringFree(&ptszStringBinding); if( RPC_S_OK != rpcstatus ) { _tprintf( TEXT("Failed RpcBindingFromStringBinding (%d)\n"), rpcstatus ); hr = HRESULT_FROM_WIN32( rpcstatus ); goto Exit; } fBound = TRUE;
// Call up to TrkSvr
__try { hr = LnkSvrMessage(BindingHandle, &Msg); } __except( EXCEPTION_EXECUTE_HANDLER ) { hr = HRESULT_FROM_WIN32( GetExceptionCode() ); } if( FAILED(hr) ) { _tprintf( TEXT("Failed LnkSvrMessage RPC (%08x)\n"), hr ); goto Exit; }
// Dump the results
_tprintf( TEXT("\n") ); _tprintf( TEXT("%-35s\t%d.%d (Build %d)\n"), TEXT("Version"), Msg.Statistics.Version.dwMajor, Msg.Statistics.Version.dwMinor, Msg.Statistics.Version.dwBuildNumber );
_tprintf( TEXT("\n") ); _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("SyncVolume Requests/Errors/Threads"), Msg.Statistics.cSyncVolumeRequests, Msg.Statistics.cSyncVolumeErrors, Msg.Statistics.cSyncVolumeThreads );
_tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" CreateVolume Requests/Errors"), Msg.Statistics.cCreateVolumeRequests, Msg.Statistics.cCreateVolumeErrors ); _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" ClaimVolume Requests/Errors"), Msg.Statistics.cClaimVolumeRequests, Msg.Statistics.cClaimVolumeErrors ); _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" QueryVolume Requests/Errors"), Msg.Statistics.cQueryVolumeRequests, Msg.Statistics.cQueryVolumeErrors ); _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" FindVolume Requests/Errors"), Msg.Statistics.cFindVolumeRequests, Msg.Statistics.cFindVolumeErrors ); _tprintf( TEXT("%-35s\t%d\t%d\n"), TEXT(" TestVolume Requests/Errors"), Msg.Statistics.cTestVolumeRequests, Msg.Statistics.cTestVolumeErrors );
_tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("Search Requests/Errors/Threads"), Msg.Statistics.cSearchRequests, Msg.Statistics.cSearchErrors, Msg.Statistics.cSearchThreads ); _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("MoveNotify Requests/Errors/Threads"), Msg.Statistics.cMoveNotifyRequests, Msg.Statistics.cMoveNotifyErrors, Msg.Statistics.cMoveNotifyThreads ); _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("Refresh Requests/Errors/Threads"), Msg.Statistics.cRefreshRequests, Msg.Statistics.cRefreshErrors, Msg.Statistics.cRefreshThreads ); _tprintf( TEXT("%-35s\t%d\t%d\t%d\n"), TEXT("DeleteNotify Requests/Errors/Threads"), Msg.Statistics.cDeleteNotifyRequests, Msg.Statistics.cDeleteNotifyErrors, Msg.Statistics.cDeleteNotifyThreads );
_tprintf( TEXT("\n") ); cftLocal = static_cast<CFILETIME>(Msg.Statistics.ftServiceStart).ConvertUtcToLocal(); cftLocal.Stringize( ELEMENTS(tszLocalFileTime), tszLocalFileTime ); _tprintf( TEXT("%-35s\t%08x:%08x\n%35s\t(%s local time)\n"), TEXT("Service start"), Msg.Statistics.ftServiceStart.dwHighDateTime, Msg.Statistics.ftServiceStart.dwLowDateTime, TEXT(""), tszLocalFileTime );
cftLocal = static_cast<CFILETIME>(Msg.Statistics.ftLastSuccessfulRequest).ConvertUtcToLocal(); cftLocal.Stringize( ELEMENTS(tszLocalFileTime), tszLocalFileTime ); _tprintf( TEXT("%-35s\t%08x:%08x\n%35s\t(%s local time)\n"), TEXT("Last successful request"), Msg.Statistics.ftLastSuccessfulRequest.dwHighDateTime, Msg.Statistics.ftLastSuccessfulRequest.dwLowDateTime, TEXT(""), tszLocalFileTime ); _tprintf( TEXT("%-35s\t%08x\n"), TEXT("Last Error"), Msg.Statistics.hrLastError );
_tprintf( TEXT("\nQuota Information:\n") ); _tprintf( TEXT(" %-32s\t%d\n"), TEXT("Move Limit"), Msg.Statistics.dwMoveLimit );
_tprintf( TEXT(" %-32s\t%d\n"), TEXT("Volume table cached count"), Msg.Statistics.dwCachedVolumeTableCount ); _tprintf( TEXT(" %-32s\t%d\n"), TEXT("Move table cached count"), Msg.Statistics.dwCachedMoveTableCount );
cftLocal = static_cast<CFILETIME>(Msg.Statistics.ftCacheLastUpdated).ConvertUtcToLocal(); cftLocal.Stringize( ELEMENTS(tszLocalFileTime), tszLocalFileTime ); _tprintf( TEXT(" %-32s\t%08x:%08x\n%35s\t(%s local time)\n"), TEXT("Cache counts last updated"), Msg.Statistics.ftCacheLastUpdated.dwHighDateTime, Msg.Statistics.ftCacheLastUpdated.dwLowDateTime, TEXT(""), tszLocalFileTime );
_tprintf( TEXT(" %-32s\t%s\n"), TEXT("Is designated DC"), Msg.Statistics.fIsDesignatedDc ? TEXT("Yes") : TEXT("No") );
_tprintf( TEXT("\n") ); cftLocal = static_cast<CFILETIME>(Msg.Statistics.ftNextGC).ConvertUtcToLocal(); cftLocal.Stringize( ELEMENTS(tszLocalFileTime), tszLocalFileTime ); _tprintf( TEXT("%-35s\t%08x:%08x\n%35s\t(%s local time)\n"), TEXT("Next GC"), Msg.Statistics.ftNextGC.dwHighDateTime, Msg.Statistics.ftNextGC.dwLowDateTime, TEXT(""), tszLocalFileTime ); _tprintf( TEXT("%-35s\t%d\n"), TEXT("Entries GC-ed"), Msg.Statistics.cEntriesGCed); _tprintf( TEXT("%-35s\t%d\n"), TEXT("Max DS write events"), Msg.Statistics.cMaxDsWriteEvents); _tprintf( TEXT("%-35s\t%d\n"), TEXT("Current failed writes"), Msg.Statistics.cCurrentFailedWrites);
_tprintf( TEXT("\n") ); _tprintf( TEXT("%-35s\t%d\n"), TEXT("Refresh counter"), Msg.Statistics.lRefreshCounter ); _tprintf( TEXT("%-35s\t%d/%d/%d\n"), TEXT("Available/least/max RPC server threads"), Msg.Statistics.cAvailableRpcThreads, Msg.Statistics.cLowestAvailableRpcThreads, Msg.Statistics.cMaxRpcThreads ); _tprintf( TEXT("%-35s\t%d/%d\n"), TEXT("Current/most thread pool threads"), Msg.Statistics.cNumThreadPoolThreads, Msg.Statistics.cMostThreadPoolThreads ); /*
_tprintf( TEXT("%-35s\t%s\n"), TEXT("Service controller state"), CDebugString( static_cast<SServiceState>(Msg.Statistics.SvcCtrlState))._tsz ); */
//ShowMoveCounter( rgptszArgs[iDcName] );
} __except( EXCEPTION_EXECUTE_HANDLER ) { hr = GetExceptionCode(); }
Exit:
if( fBound ) RpcBindingFree( &BindingHandle );
return( SUCCEEDED(hr) ); }
BOOL SetRefreshCounter( CDbConnection &dbc, CLdapVolumeKeyDn dnKey, const SequenceNumber seq ) { int ldapRV; HRESULT hr = E_FAIL;
CTrkSvrConfiguration configSvr; configSvr.Initialize(); LDAPMod * mods[2];
__try { CLdapSeqNum lsn(seq); CLdapStringMod lsmSequence(s_timeRefresh, lsn, LDAP_MOD_REPLACE );
mods[0] = &lsmSequence._mod; mods[1] = 0;
ldapRV = ldap_modify_s(dbc.Ldap(), dnKey, mods);
if(LDAP_SUCCESS != ldapRV) { printf( "Failed ldap_modify_s(%lu)\n", LdapMapErrorToWin32(ldapRV) ); hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldapRV) ); __leave; }
} __finally { }
return SUCCEEDED(hr); }
class CLdapSecret { public: CLdapSecret() { memset(_abPad,0,sizeof(_abPad)); }
CLdapSecret(const CVolumeSecret &secret) { _secret = secret; memset(_abPad,0,sizeof(_abPad)); }
CVolumeSecret _secret; BYTE _abPad[sizeof(GUID) - sizeof(CVolumeSecret)]; };
BOOL DltAdminSetVolumeSeqNumber( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten ) { NTSTATUS status; HRESULT hr = S_OK;; SequenceNumber seq; CVolumeId volid; CStringize stringize;
if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] )) { printf( "\nOption SetVolSeq\n" " Purpose: Set the sequence number in a volume table entry\n" " Usage: -setvolseq <DC name> <seq> <volid>\n" " E.g.: -setvolseq ntdsdc0 90 {d763433c-73a3-48c7-88a5-d6f3552835c6}\n" " Note: Requires write access to volume table in DS.\n" ); *pcEaten = 1; return( TRUE ); }
_tprintf( TEXT("Setting sequence number in volume table\n"), rgptszArgs[0] );
if( 3 > cArgs ) { printf( "Invalid parameters. Use -? for usage info\n" ); *pcEaten = 0; return( FALSE ); }
*pcEaten = 1;
// Get the sequence number
if( 1 != _stscanf( rgptszArgs[1], TEXT("%d"), &seq )) { printf( "Invalid sequence number. Use -? for usage info\n" ); return FALSE; }
// Get the volid
// mikehill_test
DebugBreak(); stringize.Use( rgptszArgs[2] ); volid = stringize;
/*
{ RPC_STATUS rpc_status = RPC_S_INVALID_STRING_UUID; TCHAR tszTemp[ MAX_PATH ]; TCHAR *ptszTemp = NULL;
if( TEXT('{') == rgptszArgs[2][0] ) { _tcscpy( tszTemp, &rgptszArgs[2][1] ); ptszTemp = _tcschr( tszTemp, TEXT('}') ); if( NULL != ptszTemp ) {
*ptszTemp = TEXT('\0');
rpc_status = UuidFromString( tszTemp, (GUID*)&volid ); } }
if( RPC_S_OK != rpc_status ) { _tprintf( TEXT("Error: Invalid volume ID\n") ); return FALSE; } } */
// Set the sequence
CDbConnection dbc; dbc.Initialize( NULL, rgptszArgs[0] );
CLdapVolumeKeyDn dnKey(dbc.GetBaseDn(), volid);
return SetRefreshCounter( dbc, dnKey, seq ); }
BOOL SetRefreshCounter2( CDbConnection &dbc, CLdapIdtKeyDn dnKey, const SequenceNumber seq ) { int ldapRV; HRESULT hr = E_FAIL;
CTrkSvrConfiguration configSvr; configSvr.Initialize(); LDAPMod * mods[2];
__try { CLdapSeqNum lsn(seq); CLdapStringMod lsmSequence(s_timeRefresh, lsn, LDAP_MOD_REPLACE );
mods[0] = &lsmSequence._mod; mods[1] = 0;
ldapRV = ldap_modify_s(dbc.Ldap(), dnKey, mods);
if(LDAP_SUCCESS != ldapRV) { printf( "Failed ldap_modify_s(%lu)\n", LdapMapErrorToWin32(ldapRV) ); hr = HRESULT_FROM_WIN32(LdapMapErrorToWin32(ldapRV) ); __leave; }
} __finally { }
return SUCCEEDED(hr); }
BOOL DltAdminSetDroidSeqNumber( ULONG cArgs, const TCHAR * const rgptszArgs[], ULONG *pcEaten ) { NTSTATUS status; HRESULT hr = S_OK;; SequenceNumber seq; CDomainRelativeObjId droid; CStringize stringize;
if( 1 <= cArgs && IsHelpArgument( rgptszArgs[0] )) { printf( "\nOption SetDroidSeq\n" " Purpose: Set the sequence number in a move table entry\n" " Usage: -setdroidseq <DC name> <seq> <volid>\n" " E.g.: -setdroidseq ntdsdc0 90 {d763433c-73a3-48c7-88a5-d6f3552835c6}{183c8367-a392-c784-88a5-d6f3552835c6}\n" " Note: Requires write access to volume table in DS.\n" ); *pcEaten = 1; return( TRUE ); }
_tprintf( TEXT("Setting sequence number in move table\n"), rgptszArgs[0] );
if( 3 > cArgs ) { printf( "Invalid parameters. Use -? for usage info\n" ); *pcEaten = 0; return( FALSE ); }
*pcEaten = 1;
// Get the sequence number
if( 1 != _stscanf( rgptszArgs[1], TEXT("%d"), &seq )) { printf( "Invalid sequence number. Use -? for usage info\n" ); return FALSE; }
// Get the droid
stringize.Use( rgptszArgs[2] ); droid = stringize;
if( CDomainRelativeObjId() == droid ) { _tprintf( TEXT("Error: Invalid DROID\n") ); return FALSE; }
// Set the sequence
CDbConnection dbc; dbc.Initialize( NULL, rgptszArgs[0] );
CLdapIdtKeyDn dnKey(dbc.GetBaseDn(), droid);
return SetRefreshCounter2( dbc, dnKey, seq ); }
|