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.
694 lines
19 KiB
694 lines
19 KiB
/*++
|
|
|
|
Copyright (c) 1992-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ExpConf.c
|
|
|
|
Abstract:
|
|
|
|
This file contains structures, function prototypes, and definitions
|
|
for the replicator export directory worker routines.
|
|
|
|
Author:
|
|
|
|
John Rogers (JohnRo) 09-Jan-1992
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
|
|
Requires ANSI C extensions: slash-slash comments, long external names.
|
|
|
|
Revision History:
|
|
|
|
09-Jan-1992 JohnRo
|
|
Created.
|
|
23-Jan-1992 JohnRo
|
|
Clarify units for time parameters.
|
|
28-Jan-1992 JohnRo
|
|
Added ExportDirConfigDataExists() and ExportDirDeleteConfigData().
|
|
ExportDirReadConfigData() should return NERR_UnknownDevDir.
|
|
Changed to use LPTSTR etc.
|
|
03-Feb-1992 JohnRo
|
|
Corrected config _write where extent trashed integrity value.
|
|
Got rid of extra parse of comma.
|
|
Call ReplConfigReportBadParmValue() to inform user.
|
|
Corrected lengths used for integrity and extent.
|
|
10-Feb-1992 JohnRo
|
|
ExportDirReadConfigData() should handle section not found.
|
|
13-Feb-1992 JohnRo
|
|
Implement ExportDirDeleteConfigData().
|
|
Moved section name equates to ConfName.h.
|
|
26-Feb-1992 JohnRo
|
|
API records now contain timestamps instead of elapsed times.
|
|
23-Mar-1992 JohnRo
|
|
Get rid of old config helpers.
|
|
10-Jul-1992 JohnRo
|
|
RAID 10503: srv mgr: repl dialog doesn't come up.
|
|
Use PREFIX_ equates.
|
|
23-Jul-1992 JohnRo
|
|
RAID 2274: repl svc should impersonate caller.
|
|
29-Sep-1992 JohnRo
|
|
Also fix remote repl admin.
|
|
04-Dec-1992 JohnRo
|
|
RAID 3844: remote NetReplSetInfo uses local machine type.
|
|
Made changes suggested by PC-LINT 5.0
|
|
21-Jan-1993 JohnRo
|
|
RAID 7717: Repl assert if not logged on correctly. (Also do event
|
|
logging for real.)
|
|
More changes suggested by PC-LINT 5.0
|
|
25-Jan-1993 JohnRo
|
|
RAID 12914: avoid double close and free mem in ExportDirDeleteConfigData
|
|
30-Apr-1993 JohnRo
|
|
Use NetpKdPrint() where possible.
|
|
|
|
--*/
|
|
|
|
|
|
#include <windef.h> // Win32 type definitions
|
|
#include <lmcons.h> // LAN Manager common definitions
|
|
#include <repldefs.h> // IF_DEBUG(), DWORDLEN.
|
|
|
|
#include <config.h> // NetpConfig helpers.
|
|
#include <confname.h> // SECT_NT_ equates.
|
|
#include <dirname.h> // ReplIsDirNameValid().
|
|
#include <expdir.h> // My prototypes.
|
|
#include <lmapibuf.h> // NetApiBufferFree().
|
|
#include <lmerr.h> // NERR_, ERROR_, NO_ERROR equates.
|
|
#include <lmerrlog.h> // NELOG_ equates.
|
|
#include <lmrepl.h> // REPL_INTEGRITY equates, etc.
|
|
#include <netdebug.h> // NetpAssert(), etc.
|
|
#include <netlib.h> // NetpPointerPlusSomeBytes().
|
|
#include <prefix.h> // PREFIX_ equates.
|
|
#include <replconf.h> // ReplConfigReportBadParmValue().
|
|
#include <tstr.h> // STRCPY(), ATOL().
|
|
|
|
|
|
#define STRING_FILE (LPVOID) TEXT("FILE")
|
|
#define STRING_TREE (LPVOID) TEXT("TREE")
|
|
|
|
#define MAX_INTEGRITY_LEN 4
|
|
#define MAX_EXTENT_LEN 4
|
|
|
|
#define EXPORT_VALUE_ARRAY_LEN \
|
|
(MAX_INTEGRITY_LEN /* integrity */ \
|
|
+ 1 /* , */ \
|
|
+ MAX_EXTENT_LEN /* extent */ \
|
|
+ 1 /* , */ \
|
|
+ DWORDLEN /* lockcount */ \
|
|
+ 1 /* , */ \
|
|
+ DWORDLEN ) /* locktime (seconds since 1970) */
|
|
|
|
|
|
// Tells whether or not config data for this directory exists.
|
|
// Callable even if the replicator service is not started.
|
|
BOOL
|
|
ExportDirConfigDataExists (
|
|
IN LPTSTR UncServerName OPTIONAL,
|
|
IN LPTSTR DirName // Caller must check dir name syntax.
|
|
)
|
|
{
|
|
NET_API_STATUS ApiStatus;
|
|
LPNET_CONFIG_HANDLE Handle = NULL;
|
|
LPTSTR Value = NULL;
|
|
|
|
//
|
|
// Check for caller's errors.
|
|
//
|
|
NetpAssert( ReplIsDirNameValid( DirName ) );
|
|
|
|
//
|
|
// Open the right section of the config file/whatever.
|
|
//
|
|
ApiStatus = NetpOpenConfigDataEx(
|
|
& Handle,
|
|
UncServerName,
|
|
(LPTSTR) SECT_NT_REPLICATOR, // section
|
|
(LPTSTR) SECT_NT_REPLICATOR_EXPORTS, // area (instead of parameters)
|
|
TRUE); // read-only
|
|
if (ApiStatus != NO_ERROR) {
|
|
// Log error on server we were trying to access.
|
|
ReplErrorLog(
|
|
UncServerName,
|
|
NELOG_ReplSysErr,
|
|
ApiStatus,
|
|
NULL,
|
|
NULL );
|
|
return (FALSE); // section doesn't exist, so dir data doesn't.
|
|
}
|
|
|
|
//
|
|
// Read the value from the config file/whatever.
|
|
//
|
|
ApiStatus = NetpGetConfigValue(
|
|
Handle,
|
|
DirName, // keyword is dir name
|
|
& Value); // alloc and set ptr
|
|
|
|
//
|
|
// We're done with this, so close the config data and toss the buffer we
|
|
// got. But remember the status from NetpGetConfigValue!
|
|
//
|
|
if (Value != NULL) {
|
|
(void) NetApiBufferFree( Value );
|
|
}
|
|
(void) NetpCloseConfigData( Handle );
|
|
|
|
//
|
|
// Now check the status of the Get.
|
|
//
|
|
if (ApiStatus == NERR_CfgParamNotFound) {
|
|
return (FALSE); // doesn't exist
|
|
} else if (ApiStatus == NO_ERROR) {
|
|
return (TRUE); // exists
|
|
} else {
|
|
// Log error on server we were trying to access.
|
|
ReplErrorLog(
|
|
UncServerName,
|
|
NELOG_ReplSysErr,
|
|
ApiStatus,
|
|
NULL,
|
|
NULL );
|
|
return (FALSE); // Unexpected error, so assume it doesn't exist.
|
|
}
|
|
|
|
/*NOTREACHED*/
|
|
|
|
} // ExportDirConfigDataExists
|
|
|
|
|
|
// Delete config data for this directory.
|
|
// Returns NERR_UnknownDevDir if config data doesn't exist for this dir.
|
|
// Callable even if the replicator service is not started.
|
|
NET_API_STATUS
|
|
ExportDirDeleteConfigData (
|
|
IN LPTSTR UncServerName OPTIONAL,
|
|
IN LPTSTR DirName // Caller must check dir name syntax.
|
|
)
|
|
{
|
|
NET_API_STATUS ApiStatus;
|
|
LPNET_CONFIG_HANDLE Handle = NULL;
|
|
|
|
//
|
|
// Check for caller's errors.
|
|
//
|
|
if ( ! ReplIsDirNameValid( DirName ) ) {
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
//
|
|
// Open the right section of the config file/whatever.
|
|
//
|
|
ApiStatus = NetpOpenConfigDataEx(
|
|
& Handle,
|
|
UncServerName,
|
|
(LPTSTR) SECT_NT_REPLICATOR, // section
|
|
(LPTSTR) SECT_NT_REPLICATOR_EXPORTS, // area (instead of parameters)
|
|
FALSE ); // not read-only
|
|
if (ApiStatus == NERR_CfgCompNotFound) {
|
|
ApiStatus = NERR_UnknownDevDir;
|
|
goto Cleanup; // go log error
|
|
} else if (ApiStatus != NO_ERROR) {
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
//
|
|
// Delete this keyword from this section.
|
|
//
|
|
ApiStatus = NetpDeleteConfigKeyword(
|
|
Handle,
|
|
DirName ); // keyword is dir name
|
|
|
|
IF_DEBUG(EXPAPI) {
|
|
NetpKdPrint(( PREFIX_REPL
|
|
"ExportDirDeleteConfigData( " FORMAT_LPTSTR " ): conf del ret "
|
|
FORMAT_API_STATUS ".\n",
|
|
(UncServerName!=NULL) ? UncServerName : (LPTSTR) TEXT("local"),
|
|
ApiStatus ));
|
|
}
|
|
|
|
if (ApiStatus == NERR_CfgParamNotFound) {
|
|
ApiStatus = NERR_UnknownDevDir;
|
|
goto Cleanup; // go log error
|
|
} else if (ApiStatus != NO_ERROR) {
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
//
|
|
// All done.
|
|
//
|
|
if ( Handle != NULL ) {
|
|
NET_API_STATUS CloseStatus;
|
|
|
|
CloseStatus = NetpCloseConfigData( Handle );
|
|
|
|
// Return this error iff it is first error we've gotten.
|
|
if ( (ApiStatus == NO_ERROR) && (CloseStatus != NO_ERROR) ) {
|
|
ApiStatus = CloseStatus;
|
|
}
|
|
}
|
|
|
|
if (ApiStatus != NO_ERROR) {
|
|
|
|
// Log error on server we were trying to access.
|
|
ReplErrorLog(
|
|
UncServerName,
|
|
NELOG_ReplSysErr,
|
|
ApiStatus,
|
|
NULL,
|
|
NULL );
|
|
}
|
|
|
|
return (ApiStatus);
|
|
|
|
} // ExportDirDeleteConfigData
|
|
|
|
|
|
// Parse config data for a single export directory. Callable whether or not
|
|
// the replicator service is started. (This function is used in this file
|
|
// and by the NetReplExportDirEnum routine.)
|
|
NET_API_STATUS
|
|
ExportDirParseConfigData (
|
|
IN LPTSTR UncServerName OPTIONAL,
|
|
IN LPTSTR ValueString,
|
|
OUT LPDWORD IntegrityPtr,
|
|
OUT LPDWORD ExtentPtr,
|
|
OUT LPDWORD LockCountPtr,
|
|
OUT LPDWORD LockTimePtr // Seconds since 1970.
|
|
)
|
|
{
|
|
LPTSTR CurrentValuePtr = ValueString;
|
|
|
|
//
|
|
// Check for caller's errors.
|
|
//
|
|
NetpAssert( ValueString != NULL );
|
|
if (STRLEN( ValueString ) > EXPORT_VALUE_ARRAY_LEN) {
|
|
goto ReportBadConfigLine;
|
|
}
|
|
|
|
//
|
|
// Start parsing the value, which begins with a string containing the
|
|
// integrity.
|
|
//
|
|
|
|
#define TRY_INTEGRITY( IntegrityEquate, IntegrityString ) \
|
|
{ \
|
|
DWORD HopefulStringLength = STRLEN(IntegrityString); \
|
|
if (STRNCMP( CurrentValuePtr, (IntegrityString), HopefulStringLength) == 0) { \
|
|
*IntegrityPtr = (IntegrityEquate); \
|
|
CurrentValuePtr = (LPTSTR) (LPVOID) \
|
|
NetpPointerPlusSomeBytes( CurrentValuePtr, \
|
|
HopefulStringLength * sizeof(TCHAR) ); \
|
|
goto DoneIntegrity; \
|
|
} \
|
|
}
|
|
|
|
TRY_INTEGRITY( REPL_INTEGRITY_FILE, STRING_FILE )
|
|
|
|
TRY_INTEGRITY( REPL_INTEGRITY_TREE, STRING_TREE )
|
|
|
|
goto ReportBadConfigLine;
|
|
|
|
DoneIntegrity:
|
|
|
|
//
|
|
// Parse the comma after the integrity string.
|
|
//
|
|
|
|
#define PARSE_CHAR(AsciiChar) \
|
|
{ \
|
|
if (*CurrentValuePtr == MAKE_TCHAR(AsciiChar)) { \
|
|
++CurrentValuePtr; \
|
|
} else { \
|
|
goto ReportBadConfigLine; \
|
|
} \
|
|
}
|
|
|
|
#define PARSE_COMMA( ) PARSE_CHAR(',')
|
|
|
|
PARSE_COMMA();
|
|
|
|
//
|
|
// Now do the extent string.
|
|
//
|
|
|
|
#define TRY_EXTENT( ExtentEquate, ExtentString ) \
|
|
{ \
|
|
DWORD HopefulStringLength = STRLEN(ExtentString); \
|
|
if (STRNCMP( CurrentValuePtr, (ExtentString), HopefulStringLength) == 0) { \
|
|
*ExtentPtr = (ExtentEquate); \
|
|
CurrentValuePtr = (LPTSTR) (LPVOID) \
|
|
NetpPointerPlusSomeBytes( CurrentValuePtr, \
|
|
HopefulStringLength * sizeof(TCHAR) ); \
|
|
goto DoneExtent; \
|
|
} \
|
|
}
|
|
|
|
TRY_EXTENT( REPL_EXTENT_FILE, STRING_FILE )
|
|
|
|
TRY_EXTENT( REPL_EXTENT_TREE, STRING_TREE )
|
|
|
|
goto ReportBadConfigLine;
|
|
|
|
DoneExtent:
|
|
|
|
PARSE_COMMA();
|
|
|
|
//
|
|
// Parse the numbers on the rest of the line.
|
|
//
|
|
|
|
#define PARSE_DWORD( NumberPtr ) \
|
|
{ \
|
|
if ( ! ISDIGIT( *CurrentValuePtr ) ) { \
|
|
goto ReportBadConfigLine; \
|
|
} \
|
|
NetpAssert( NumberPtr != NULL ); \
|
|
* NumberPtr = (DWORD) ATOL( CurrentValuePtr ); \
|
|
while ( ISDIGIT( *CurrentValuePtr ) ) { \
|
|
++CurrentValuePtr; \
|
|
} \
|
|
}
|
|
|
|
PARSE_DWORD( LockCountPtr );
|
|
|
|
PARSE_COMMA();
|
|
|
|
PARSE_DWORD( LockTimePtr );
|
|
|
|
IF_DEBUG(EXPAPI) {
|
|
NetpKdPrint(( PREFIX_REPL
|
|
"ExportDirParseConfigValue: Value = '" FORMAT_LPTSTR "',\n",
|
|
ValueString ));
|
|
NetpKdPrint((
|
|
" Integrity = " FORMAT_DWORD
|
|
", Extent = " FORMAT_DWORD
|
|
", lock count = " FORMAT_DWORD ".\n",
|
|
*IntegrityPtr, *ExtentPtr, *LockCountPtr ));
|
|
NetpDbgDisplayTimestamp( "lock time", *LockTimePtr );
|
|
}
|
|
|
|
if ( ! ReplIsIntegrityValid( *IntegrityPtr ) ) {
|
|
goto ReportBadConfigLine;
|
|
}
|
|
if ( ! ReplIsExtentValid( *ExtentPtr ) ) {
|
|
goto ReportBadConfigLine;
|
|
}
|
|
|
|
return (NO_ERROR);
|
|
|
|
ReportBadConfigLine:
|
|
|
|
// BUGBUG: Sure would be nice if we could include dirname here.
|
|
|
|
ReplConfigReportBadParmValue(
|
|
UncServerName,
|
|
(LPTSTR) SECT_NT_REPLICATOR_EXPORTS,
|
|
ValueString );
|
|
return (ERROR_INVALID_DATA);
|
|
|
|
} // ExportDirParseConfigData
|
|
|
|
|
|
// Read config data for a single export directory. Callable whether or not
|
|
// the replicator service is started. Returns NERR_UnknownDevDir if no
|
|
// config data exists for this directory.
|
|
NET_API_STATUS
|
|
ExportDirReadConfigData (
|
|
IN LPTSTR UncServerName OPTIONAL,
|
|
IN LPTSTR DirName,
|
|
OUT LPDWORD IntegrityPtr,
|
|
OUT LPDWORD ExtentPtr,
|
|
OUT LPDWORD LockCountPtr,
|
|
OUT LPDWORD LockTimePtr // Seconds since 1970.
|
|
)
|
|
{
|
|
NET_API_STATUS ApiStatus;
|
|
LPNET_CONFIG_HANDLE Handle = NULL;
|
|
LPTSTR Value = NULL;
|
|
|
|
//
|
|
// Check for caller's errors.
|
|
//
|
|
if ( ! ReplIsDirNameValid( DirName ) ) {
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
//
|
|
// Open the right section of the config file/whatever.
|
|
//
|
|
ApiStatus = NetpOpenConfigDataEx(
|
|
& Handle,
|
|
UncServerName,
|
|
(LPTSTR) SECT_NT_REPLICATOR, // section
|
|
(LPTSTR) SECT_NT_REPLICATOR_EXPORTS, // area (instead of parameters)
|
|
TRUE); // read-only
|
|
if (ApiStatus == NERR_CfgCompNotFound) {
|
|
ApiStatus = NERR_UnknownDevDir;
|
|
goto Cleanup; // go log error
|
|
} else if (ApiStatus != NO_ERROR) {
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
//
|
|
// Read the value from the config file/whatever.
|
|
//
|
|
ApiStatus = NetpGetConfigValue(
|
|
Handle,
|
|
DirName, // keyword is dir name
|
|
& Value); // alloc and set ptr
|
|
if (ApiStatus == NERR_CfgParamNotFound) {
|
|
ApiStatus = NERR_UnknownDevDir;
|
|
goto Cleanup; // go log error
|
|
} else if (ApiStatus != NO_ERROR) {
|
|
goto Cleanup; // go log error
|
|
}
|
|
NetpAssert( Value != NULL );
|
|
|
|
IF_DEBUG(EXPAPI) {
|
|
NetpKdPrint(( PREFIX_REPL
|
|
"ExportDirReadConfigValue( " FORMAT_LPTSTR " ): '"
|
|
FORMAT_LPTSTR "' = '" FORMAT_LPTSTR "'.\n",
|
|
(UncServerName!=NULL) ? UncServerName : (LPTSTR) TEXT("local"),
|
|
DirName, Value ));
|
|
}
|
|
|
|
//
|
|
// Parse the value string...
|
|
//
|
|
ApiStatus = ExportDirParseConfigData (
|
|
UncServerName,
|
|
Value,
|
|
IntegrityPtr,
|
|
ExtentPtr,
|
|
LockCountPtr,
|
|
LockTimePtr); // Seconds since 1970.
|
|
// Fall through and log error if any.
|
|
|
|
Cleanup:
|
|
|
|
//
|
|
// All done.
|
|
//
|
|
if ( Handle != NULL ) {
|
|
NET_API_STATUS CloseStatus;
|
|
|
|
CloseStatus = NetpCloseConfigData( Handle );
|
|
|
|
// Return this error iff it is first error we've gotten.
|
|
if ( (ApiStatus == NO_ERROR) && (CloseStatus != NO_ERROR) ) {
|
|
ApiStatus = CloseStatus;
|
|
}
|
|
}
|
|
|
|
(VOID) NetApiBufferFree( Value );
|
|
|
|
if (ApiStatus != NO_ERROR) {
|
|
|
|
// Log error on server we were trying to access.
|
|
ReplErrorLog(
|
|
UncServerName,
|
|
NELOG_ReplSysErr,
|
|
ApiStatus,
|
|
NULL,
|
|
NULL );
|
|
}
|
|
return (ApiStatus);
|
|
|
|
} // ExportDirReadConfigData
|
|
|
|
|
|
|
|
|
|
|
|
// Write config data for a single export directory. Callable whether or not
|
|
// the replicator service is started.
|
|
NET_API_STATUS
|
|
ExportDirWriteConfigData (
|
|
IN LPTSTR UncServerName OPTIONAL,
|
|
IN LPTSTR DirName,
|
|
IN DWORD Integrity,
|
|
IN DWORD Extent,
|
|
IN DWORD LockCount,
|
|
IN DWORD LockTime // Seconds since 1970.
|
|
)
|
|
{
|
|
NET_API_STATUS ApiStatus;
|
|
LPNET_CONFIG_HANDLE Handle = NULL;
|
|
TCHAR ValueArray[EXPORT_VALUE_ARRAY_LEN+1];
|
|
|
|
//
|
|
// Check for caller's errors.
|
|
//
|
|
if ( ! ReplIsDirNameValid( DirName ) ) {
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup; // go log error
|
|
}
|
|
if ( ! ReplIsIntegrityValid( Integrity ) ) {
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup; // go log error
|
|
}
|
|
if ( ! ReplIsExtentValid( Extent ) ) {
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
//
|
|
// Open the right section of the config file/whatever.
|
|
//
|
|
ApiStatus = NetpOpenConfigDataEx(
|
|
& Handle,
|
|
UncServerName,
|
|
(LPTSTR) SECT_NT_REPLICATOR, // section
|
|
(LPTSTR) SECT_NT_REPLICATOR_EXPORTS, // area (instead of parameters)
|
|
FALSE); // not read-only
|
|
if (ApiStatus != NO_ERROR) {
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
//
|
|
// Start building the value, which begins with a string containing the
|
|
// integrity.
|
|
//
|
|
switch (Integrity) {
|
|
case REPL_INTEGRITY_FILE:
|
|
|
|
(void) STRCPY( ValueArray, STRING_FILE);
|
|
break;
|
|
|
|
case REPL_INTEGRITY_TREE:
|
|
|
|
(void) STRCPY( ValueArray, STRING_TREE);
|
|
break;
|
|
|
|
default:
|
|
NetpAssert( FALSE );
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
//
|
|
// Fields get seperated by commas.
|
|
//
|
|
/*lint -save -e767 */ // Don't complain about different definitions
|
|
#define WRITE_COMMA( ) \
|
|
(void) STRCAT( ValueArray, (LPVOID) TEXT(",") )
|
|
/*lint -restore */ // Resume checking for different macro definitions
|
|
|
|
WRITE_COMMA();
|
|
|
|
//
|
|
// Next we do the extent.
|
|
//
|
|
switch (Extent) {
|
|
case REPL_EXTENT_FILE:
|
|
|
|
(void) STRCAT( ValueArray, STRING_FILE);
|
|
break;
|
|
|
|
case REPL_EXTENT_TREE:
|
|
|
|
(void) STRCAT( ValueArray, STRING_TREE);
|
|
break;
|
|
|
|
default:
|
|
NetpAssert( FALSE );
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup; // go log error
|
|
}
|
|
|
|
WRITE_COMMA();
|
|
|
|
//
|
|
// Now do the last two fields, with are both DWORDS.
|
|
//
|
|
|
|
/*lint -save -e767 */ // Don't complain about different definitions
|
|
#define WRITE_DWORD( Number ) \
|
|
{ \
|
|
LPTSTR StrEnd = & ValueArray[ STRLEN( ValueArray ) ]; \
|
|
(void) ULTOA( (Number), StrEnd, /* radix */ 10 ); \
|
|
}
|
|
/*lint -restore */ // Resume checking for different macro definitions
|
|
|
|
WRITE_DWORD( LockCount );
|
|
|
|
WRITE_COMMA();
|
|
|
|
WRITE_DWORD( LockTime ); // Seconds since 1970.
|
|
|
|
IF_DEBUG(EXPAPI) {
|
|
NetpKdPrint(( PREFIX_REPL
|
|
"ExportDirWriteConfigValue( " FORMAT_LPTSTR "): '"
|
|
FORMAT_LPTSTR "' = '" FORMAT_LPTSTR "'.\n",
|
|
(UncServerName!=NULL) ? UncServerName : (LPVOID) TEXT("local"),
|
|
DirName, ValueArray ));
|
|
}
|
|
|
|
//
|
|
// Write this value out to the config file/whatever.
|
|
//
|
|
ApiStatus = NetpSetConfigValue(
|
|
Handle,
|
|
DirName, // keyword is dir name
|
|
ValueArray);
|
|
// Faill through and log error if any.
|
|
|
|
|
|
Cleanup:
|
|
|
|
//
|
|
// All done.
|
|
//
|
|
if ( Handle != NULL ) {
|
|
NET_API_STATUS CloseStatus;
|
|
|
|
CloseStatus = NetpCloseConfigData( Handle );
|
|
|
|
// Return this error iff it is first error we've gotten.
|
|
if ( (ApiStatus == NO_ERROR) && (CloseStatus != NO_ERROR) ) {
|
|
ApiStatus = CloseStatus;
|
|
}
|
|
}
|
|
|
|
if (ApiStatus != NO_ERROR) {
|
|
|
|
// Log error on server we were trying to access.
|
|
ReplErrorLog(
|
|
UncServerName,
|
|
NELOG_ReplSysErr,
|
|
ApiStatus,
|
|
NULL,
|
|
NULL );
|
|
}
|
|
|
|
return (ApiStatus);
|
|
|
|
} // ExportDirWriteConfigData
|