mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
321 lines
9.3 KiB
321 lines
9.3 KiB
/*++
|
|
|
|
Copyright (c) 1991-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ImpEnum.c
|
|
|
|
Abstract:
|
|
|
|
ImporDirEnumApiRecords.
|
|
|
|
Author:
|
|
|
|
John Rogers (JohnRo) 17-Dec-1991
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
16-Nov-1992 JohnRo
|
|
RAID 1537: Repl APIs in wrong role kill svc. (Extracted from DLL stub.)
|
|
01-Dec-1992 JohnRo
|
|
RAID 3844: remote NetReplSetInfo uses local machine type.
|
|
10-Mar-1993 JohnRo
|
|
RAID 12871: replication UI shows nothing (adding entry while enumerating
|
|
results in empty list).
|
|
Made changes suggested by PC-LINT 5.0
|
|
Use NetpKdPrint() where possible.
|
|
|
|
--*/
|
|
|
|
|
|
// These must be included first:
|
|
|
|
#include <windows.h> // IN, DWORD, etc.
|
|
#include <lmcons.h> // NET_API_STATUS, etc.
|
|
|
|
// These may be included in any order:
|
|
|
|
#include <config.h> // LPNET_CONFIG_HANDLE, Netp config routines.
|
|
#include <confname.h> // SECT_NT_ equates.
|
|
#include <dirname.h> // ReplIsDirNameValid().
|
|
#include <impdir.h> // My prototype.
|
|
#include <lmerr.h> // NERR_ and ERROR_ equates, NO_ERROR.
|
|
#include <lmerrlog.h> // NELOG_ equates.
|
|
#include <netdebug.h> // NetpAssert(), NetpKdPrint(), etc.
|
|
#include <prefix.h> // PREFIX_ equates.
|
|
#include <repldefs.h> // IF_DEBUG(), ReplErrorLog(), etc.
|
|
#include <strucinf.h> // NetpReplImportDirStructureInfo().
|
|
|
|
|
|
|
|
// Callable even if the replicator service is not started.
|
|
NET_API_STATUS
|
|
ImportDirEnumApiRecords(
|
|
IN LPTSTR UncServerName OPTIONAL,
|
|
IN DWORD Level,
|
|
OUT LPBYTE * BufPtr,
|
|
IN DWORD PrefMaxSize,
|
|
OUT LPDWORD EntriesRead,
|
|
OUT LPDWORD TotalEntries
|
|
)
|
|
|
|
{
|
|
NET_API_STATUS ApiStatus;
|
|
|
|
LPVOID ArrayEntry;
|
|
LPVOID ArrayStart = NULL;
|
|
DWORD EntriesAllocated = 0;
|
|
DWORD EntriesFound = 0;
|
|
BOOL FirstTime;
|
|
DWORD FixedEntrySize;
|
|
LPNET_CONFIG_HANDLE Handle = NULL;
|
|
LPBYTE StringLocation;
|
|
|
|
UNREFERENCED_PARAMETER( PrefMaxSize );
|
|
|
|
IF_DEBUG( IMPAPI ) {
|
|
NetpKdPrint(( PREFIX_REPL
|
|
"ImportDirEnumApiRecords( " FORMAT_LPTSTR
|
|
" ): doing parameter checks...\n",
|
|
(UncServerName!=NULL) ? UncServerName : (LPTSTR) TEXT("local")
|
|
));
|
|
}
|
|
|
|
if ( ! ImportDirIsLevelValid( Level ) ) {
|
|
ApiStatus = ERROR_INVALID_LEVEL;
|
|
goto Cleanup;
|
|
} else if (BufPtr == NULL) {
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
} else if (EntriesRead == NULL) {
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
} else if (TotalEntries == NULL) {
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Set outputs in case we run into an error.
|
|
//
|
|
|
|
* BufPtr = NULL;
|
|
* EntriesRead = 0;
|
|
* TotalEntries = 0;
|
|
|
|
//
|
|
// Figure-out the size of a fixed entry for this info level.
|
|
//
|
|
ApiStatus = NetpReplImportDirStructureInfo (
|
|
Level,
|
|
PARMNUM_ALL,
|
|
TRUE, // want native sizes
|
|
NULL, // don't need data desc 16
|
|
NULL, // don't need data desc 32
|
|
NULL, // don't need data desc SMB
|
|
NULL, // don't need max size
|
|
& FixedEntrySize,
|
|
NULL ); // don't need string size
|
|
|
|
NetpAssert( ApiStatus == NO_ERROR ); // Already checked args.
|
|
NetpAssert( FixedEntrySize > 0 );
|
|
|
|
//
|
|
// Open the right section of the config file/whatever.
|
|
//
|
|
ApiStatus = NetpOpenConfigDataEx(
|
|
& Handle,
|
|
UncServerName,
|
|
(LPTSTR) SECT_NT_REPLICATOR, // service name
|
|
(LPTSTR) SECT_NT_REPLICATOR_IMPORTS, // area under service
|
|
TRUE); // read-only
|
|
if (ApiStatus != NO_ERROR) {
|
|
|
|
// Handle section not found as empty enum array (not error).
|
|
if (ApiStatus == NERR_CfgCompNotFound) {
|
|
ApiStatus = NO_ERROR;
|
|
goto Cleanup;
|
|
}
|
|
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Loop, expanding buffer if necessary, until we get it large enough.
|
|
//
|
|
|
|
do {
|
|
|
|
//
|
|
// Count entries in config data.
|
|
//
|
|
ApiStatus = NetpNumberOfConfigKeywords (
|
|
Handle,
|
|
& EntriesAllocated );
|
|
|
|
if (ApiStatus != NO_ERROR) {
|
|
goto Cleanup;
|
|
} else if (EntriesAllocated == 0) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Alloc and/or expand the array...
|
|
//
|
|
ApiStatus = ImportDirAllocApiRecords (
|
|
Level,
|
|
EntriesAllocated,
|
|
(LPBYTE *) (LPVOID) & ArrayStart,
|
|
& StringLocation ); // Points just past top of data.
|
|
if (ApiStatus == NO_ERROR) {
|
|
NetpAssert( ArrayStart != NULL );
|
|
} else {
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Go back and reread, filling-in the config data as we go.
|
|
//
|
|
|
|
ArrayEntry = ArrayStart;
|
|
FirstTime = TRUE;
|
|
|
|
while (ApiStatus == NO_ERROR) {
|
|
LPTSTR DirName;
|
|
DWORD LockCount;
|
|
DWORD State;
|
|
DWORD TimeOfFirstLock; // Seconds since 1970.
|
|
DWORD TimeOfLastUpdate; // Seconds since 1970.
|
|
TCHAR UncMaster[UNCLEN+1];
|
|
LPTSTR ValueString;
|
|
|
|
ApiStatus = NetpEnumConfigSectionValues (
|
|
Handle,
|
|
& DirName, // Keyword - alloc and set ptr.
|
|
& ValueString, // Must be freed by NetApiBufferFree().
|
|
FirstTime );
|
|
|
|
FirstTime = FALSE;
|
|
|
|
if (ApiStatus == NO_ERROR) {
|
|
NetpAssert( DirName != NULL );
|
|
NetpAssert( ValueString != NULL );
|
|
|
|
++EntriesFound;
|
|
if (EntriesFound > EntriesAllocated) {
|
|
EntriesFound = 0;
|
|
NetpMemoryFree( ArrayStart );
|
|
ArrayStart = NULL;
|
|
ApiStatus = ERROR_MORE_DATA;
|
|
break; // exit per-entry loop and try again
|
|
}
|
|
|
|
if ( !ReplIsDirNameValid( DirName ) ) {
|
|
// BUGBUG: perhaps delete entry, log event, and continue?
|
|
ApiStatus = ERROR_INVALID_DATA;
|
|
NetpMemoryFree( DirName );
|
|
NetpMemoryFree( ValueString );
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Parse the value string...
|
|
//
|
|
ApiStatus = ImportDirParseConfigData (
|
|
UncServerName,
|
|
ValueString,
|
|
& State,
|
|
UncMaster,
|
|
& TimeOfLastUpdate, // Seconds since 1970.
|
|
& LockCount,
|
|
& TimeOfFirstLock ); // Seconds since 1970.
|
|
|
|
NetpMemoryFree( ValueString );
|
|
|
|
if (ApiStatus == NO_ERROR) {
|
|
LPTSTR MasterName;
|
|
NetpAssert( ArrayEntry != NULL );
|
|
|
|
if (*UncMaster) {
|
|
MasterName = UncMaster + 2; // Chg from UNC to non.
|
|
} else {
|
|
MasterName = NULL;
|
|
}
|
|
|
|
//
|
|
// Build API record for this entry.
|
|
//
|
|
ApiStatus = ImportDirBuildApiRecord (
|
|
Level,
|
|
DirName,
|
|
State, // State when svc was running.
|
|
MasterName,
|
|
TimeOfLastUpdate, // Seconds since 1970.
|
|
LockCount,
|
|
TimeOfFirstLock, // Seconds since 1970.
|
|
ArrayEntry,
|
|
& StringLocation );
|
|
if (ApiStatus != NO_ERROR) {
|
|
NetpKdPrint(( PREFIX_REPL
|
|
"ImportDirEnumApiRecords: error "
|
|
FORMAT_API_STATUS " from imp build.\n",
|
|
ApiStatus ));
|
|
NetpAssert( FALSE );
|
|
goto Cleanup;
|
|
}
|
|
|
|
ArrayEntry = NetpPointerPlusSomeBytes(
|
|
ArrayEntry, FixedEntrySize );
|
|
}
|
|
NetpMemoryFree( DirName );
|
|
|
|
}
|
|
|
|
} // while not error (may be NERR_CfgParamNotFound at end).
|
|
|
|
if (ApiStatus == NERR_CfgParamNotFound) {
|
|
ApiStatus = NO_ERROR;
|
|
} else {
|
|
NetpAssert( ApiStatus != NO_ERROR );
|
|
goto Cleanup;
|
|
}
|
|
|
|
} while (ApiStatus == ERROR_MORE_DATA);
|
|
|
|
//
|
|
// All done.
|
|
//
|
|
|
|
Cleanup:
|
|
|
|
if (Handle != NULL) {
|
|
(VOID) NetpCloseConfigData( Handle );
|
|
}
|
|
|
|
NetpAssert( ApiStatus != ERROR_MORE_DATA );
|
|
if (ApiStatus == NO_ERROR) {
|
|
* BufPtr = ArrayStart;
|
|
* EntriesRead = EntriesFound;
|
|
* TotalEntries = EntriesFound;
|
|
} else {
|
|
NetpKdPrint(( PREFIX_REPL
|
|
"ImportDirEnumApiRecords: returning status " FORMAT_API_STATUS
|
|
".\n", ApiStatus ));
|
|
|
|
// Log the error.
|
|
ReplErrorLog(
|
|
UncServerName, // log here and there.
|
|
NELOG_ReplSysErr,
|
|
ApiStatus,
|
|
NULL, // no str1
|
|
NULL ); // no str2
|
|
}
|
|
|
|
return ApiStatus;
|
|
|
|
}
|