Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1360 lines
33 KiB

#if 0 // Entire file is obsolete. --JR, 28-Jan-1992
/*++
Copyright (c) 1987-92 Microsoft Corporation
Module Name:
parse.c
Abstract:
Contains function Parse, that parses and validates all service parms.
Author:
Ported from Lan Man 2.x
Environment:
User mode only.
Contains NT-specific code.
Requires ANSI C extensions: slash-slash comments, long external names.
Tab size is set to 4.
Revision History:
03/22/89 (yuv)
initila coding
10/28/91 (madana)
ported to NT. Converted to NT style.
20-Jan-1992 JohnRo
Avoid using private logon functions.
Added config list lock.
Removed support for lanman dir switch and/or config keyword.
The tryuser variable should be treated as a BOOL.
Changed to use my config.h helpers.
Renamed wcstol() to wtol().
Added some debug output.
Use SECT_NT_REPLICATOR in config.h instead of REPL_SECTION.
Made changes suggested by PC-LINT.
23-Jan-1992 JohnRo
Added ReplConfigReportBadParmValue().
We're updating in-memory copy of config data, so we need exclusive
lock on ReplGlobalConfigLock.
Moved current role from P_repl_sw to ReplGlobalRole.
Use REPL_ROLE_ equates just like the APIs do.
Made just about everything DBGSTATIC.
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windef.h> // MAX_PATH, etc.
#include <winbase.h>
#include <lmcons.h>
#include <netdebug.h> // NetpKdPrint(()), etc. (Needed by config.h)
#include <config.h> // NetpConfig routines, SECT_NT_REPLICATOR, etc.
#include <netlib.h>
#include <netlock.h> // ACQUIRE_LOCK(), etc.
#include <lmerr.h> // NO_ERROR, ERROR_ and NERR_ equates.
#include <lmerrlog.h>
#include <lmrepl.h> // REPL_ROLE_ equates.
#include <lmsvc.h>
#include <icanon.h>
#include <tstring.h> // NetpAlloc{type}From{type}(), wtol(), etc.
#include <stdlib.h>
#include <replconf.h> // ReplGlobalConfigLock, ReplConfigReportBadParmValue().
#include <repldefs.h>
#include <iniparm.h>
#include <wcslocal.h>
DBGSTATIC LPTSTR rep_REPL = SW_REPL_REPL;
DBGSTATIC LPTSTR rep_EXPPATH = SW_REPL_EXPPATH;
DBGSTATIC LPTSTR rep_IMPPATH = SW_REPL_IMPPATH;
DBGSTATIC LPTSTR rep_EXPLIST = SW_REPL_EXPLIST;
DBGSTATIC LPTSTR rep_IMPLIST = SW_REPL_IMPLIST;
DBGSTATIC LPTSTR rep_TRYUSER = SW_REPL_TRYUSER;
DBGSTATIC LPTSTR rep_LOGON = SW_REPL_LOGON;
DBGSTATIC LPTSTR rep_PASSWD = SW_REPL_PASSWD;
DBGSTATIC LPTSTR rep_SYNC = SW_REPL_SYNCH;
DBGSTATIC LPTSTR rep_PULSE = SW_REPL_PULSE;
DBGSTATIC LPTSTR rep_GUARD = SW_REPL_GUARD;
DBGSTATIC LPTSTR rep_RANDOM = SW_REPL_RANDOM;
DBGSTATIC LPWSTR def_P_repl = DEFAULT_REPL;
DBGSTATIC LPWSTR def_P_exppath = DEFAULT_EXPPATH;
DBGSTATIC LPWSTR def_P_imppath = DEFAULT_IMPPATH;
DBGSTATIC LPWSTR def_P_explist = DEFAULT_EXPLIST;
DBGSTATIC LPWSTR def_P_implist = DEFAULT_IMPLIST;
DBGSTATIC LPWSTR def_P_logon = DEFAULT_LOGON;
DBGSTATIC LPWSTR def_P_passwd = DEFAULT_PASSWD;
//
// The following items are initialized at program start.
// They are also locked by ReplGlobalConfigLock.
//
LPWSTR P_repl = DEFAULT_REPL;
LPWSTR P_exppath = DEFAULT_EXPPATH;
LPWSTR P_imppath = DEFAULT_IMPPATH;
LPWSTR P_explist = DEFAULT_EXPLIST;
LPWSTR P_implist = DEFAULT_IMPLIST;
LPWSTR P_logon = DEFAULT_LOGON;
LPWSTR P_passwd = DEFAULT_PASSWD;
BOOL P_tryuser = DEFAULT_TRYUSER;
DWORD P_sync = DEFAULT_SYNC;
DWORD P_pulse = DEFAULT_PULSE;
DWORD P_guard = DEFAULT_GUARD;
DWORD P_random = DEFAULT_RANDOM;
DWORD ReplGlobalRole = REPL_ROLE_IMPORT;
// End of items locked by ReplGlobalConfigLock.
// prototypes
DBGSTATIC NET_API_STATUS
Parse2(
IN DWORD argc,
IN LPTSTR argv[],
IN LPNET_CONFIG_HANDLE ConfigHandle
);
DBGSTATIC NET_API_STATUS
GetParameter(
IN DWORD argc,
IN LPTSTR argv[],
IN LPNET_CONFIG_HANDLE ConfigHandle,
IN LPTSTR SwitchName,
IN OUT LPWSTR *ParmValue
);
DBGSTATIC NET_API_STATUS
GetCmdValue(
IN DWORD argc,
IN LPTSTR argv[],
IN LPTSTR SwitchName,
IN OUT LPWSTR *ParmValue
);
DBGSTATIC NET_API_STATUS
PathCheck(
IN OUT LPWSTR * Path,
IN DWORD TypeWanted,
IN LPTSTR SwitchName
);
DBGSTATIC NET_API_STATUS
ListCheck(
IN LPWSTR list,
IN LPTSTR SwitchName
);
DBGSTATIC NET_API_STATUS
DwordCheck(
IN LPWSTR StrValue OPTIONAL,
IN DWORD Min,
IN DWORD Max,
IN LPTSTR SwitchName,
IN OUT LPDWORD DwordValue
);
DBGSTATIC NET_API_STATUS
YesNoCheck(
IN LPWSTR StrValue OPTIONAL,
IN LPTSTR SwitchName,
IN OUT LPBOOL Value
);
DBGSTATIC NET_API_STATUS
NameCheck(
IN OUT LPWSTR * Name,
IN DWORD Type,
IN LPTSTR SwitchName
);
NET_API_STATUS
Parse(
IN DWORD argc,
IN LPTSTR argv[]
)
/*++
Routine Description :
Wrapper function of the real worker Parse2 function.
Arguments :
argc : argument count
argv : argument string array pointer.
Return Value :
return NO_ERROR if successfully parse parameter
ERROR_INVALID_PARAMETER, otherwise
--*/
{
NET_API_STATUS ApiStatus;
LPNET_CONFIG_HANDLE ConfigHandle;
// Get read-write lock for config data. (The lock is for the in-memory
// version of the data, which we're going to set.)
ACQUIRE_LOCK( ReplGlobalConfigLock );
// Open the config file (nt.cfg)
ApiStatus = NetpOpenConfigData(
& ConfigHandle,
NULL, // local machine
SECT_NT_REPLICATOR, // section name
TRUE); // read-only
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( "[REPL] Parse() can't open config section.\n" ));
ReplFinish(
SERVICE_UIC_CODE(
SERVICE_UIC_SYSTEM,
ApiStatus),
NULL);
RELEASE_LOCK( ReplGlobalConfigLock );
return( ApiStatus );
}
ApiStatus = Parse2(argc, argv, ConfigHandle);
// close config file ..
(void) NetpCloseConfigData( ConfigHandle );
RELEASE_LOCK( ReplGlobalConfigLock );
return( ApiStatus );
}
DBGSTATIC NET_API_STATUS
Parse2(
IN DWORD argc,
IN LPTSTR argv[],
IN LPNET_CONFIG_HANDLE ConfigHandle
)
/*++
Routine Description :
parse command line arguments, range-check them and set global
variables.
parameter units range/value default
--------- ----- ----------- -------
/REPLICATE - import/export/both REPL_ROLE_IMPORT
/EXPORTPATH pathname - repl\export
/IMPORTPATH pathname - repl\import
/EXPORTLIST names 0-32 0
/IMPORTLIST srvnames 0-32 0
/TRYUSER - yes/no YES
/LOGON username - -
/PASSWORD password - -
/INTERVAL minutes 1-60 5
/PULSE integer 1-10 3
/GUARDTIME minutes 0 to (interval/2) 2
/RANDOM seconds 1-120 60
Arguments :
argc : argument count
argv : argument string array pointer.
ConfigHandle : config handle for replicator section.
Return Value :
return NO_ERROR if successfully parse parameter
ERROR_INVALID_PARAMETER, on syntax error
and so on...
--*/
{
NET_API_STATUS ApiStatus;
LPWSTR ParmStrValue;
// get and check common parameter to master and client.
// /REPL switch
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_REPL,
&P_repl );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
if(P_repl[0] == L'\0') {
ReplConfigReportBadParmValue( rep_REPL, NULL );
return( ERROR_INVALID_PARAMETER );
}
if(_wcsicmp(P_repl, BOTH_SW) == 0) {
ReplGlobalRole = REPL_ROLE_BOTH;
}
else if(_wcsicmp(P_repl, EXPORT_SW) == 0) {
ReplGlobalRole = REPL_ROLE_EXPORT;
}
else if(_wcsicmp(P_repl, IMPORT_SW) == 0) {
ReplGlobalRole = REPL_ROLE_IMPORT;
}
else {
ReplConfigReportBadParmValue( rep_REPL, NULL );
return( ERROR_INVALID_PARAMETER );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint(( "[Repl] Repl parameter \n"));
NetpKdPrint((" REPL = %ws \n", P_repl));
}
// get and check repl master parameters
if (ReplRoleIncludesMaster( ReplGlobalRole )) {
IF_DEBUG(REPL) { // debug code
NetpKdPrint(( "[Repl] Repl master parameters \n"));
}
// EXPORTPATH
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_EXPPATH,
&P_exppath );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = PathCheck(&P_exppath, ITYPE_PATH_ABSD, rep_EXPPATH);
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" EXPORT PATH = %ws \n", P_exppath));
}
// EXPORTLIST
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_EXPLIST,
&P_explist );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = ListCheck(P_explist, rep_EXPLIST);
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" EXPORT LIST = %ws \n", P_explist));
}
// INTERVAL
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_SYNC,
&ParmStrValue );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = DwordCheck(ParmStrValue,
MIN_SYNC, MAX_SYNC, rep_SYNC, &P_sync );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" INTERVAL = 0x%lx \n", P_sync));
}
// PULSE
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_PULSE,
&ParmStrValue );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = DwordCheck(ParmStrValue,
MIN_PULSE, MAX_PULSE, rep_PULSE, &P_pulse );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" PULSE = 0x%lx \n", P_pulse));
}
// GUARD
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_GUARD,
&ParmStrValue );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = DwordCheck(ParmStrValue,
MIN_GUARD, MAX_GUARD, rep_GUARD, &P_guard );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" GUARD = 0x%lx \n", P_guard));
}
if(P_guard > (P_sync / 2)) {
NetpKdPrint(( "[REPL-MASTER] guard and sync parms conflict.\n"));
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_CONFLPARM, 0),
NULL);
return( ERROR_INVALID_PARAMETER );
}
}
if (ReplRoleIncludesClient( ReplGlobalRole )) {
IF_DEBUG(REPL) { // debug code
NetpKdPrint(( "[Repl] Repl client parameters \n"));
}
// IMPORTPATH
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_IMPPATH,
&P_imppath );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = PathCheck(&P_imppath, ITYPE_PATH_ABSD, rep_IMPPATH);
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" IMPORT PATH = %ws \n", P_imppath));
}
// IMPORTLIST
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_IMPLIST,
&P_implist );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = ListCheck(P_implist, rep_IMPLIST);
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" IMPORT LIST = %ws \n", P_implist));
}
// TRY USER
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_TRYUSER,
&ParmStrValue );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = YesNoCheck(ParmStrValue, rep_TRYUSER, &P_tryuser );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" TRYUSER = " FORMAT_DWORD "\n", (DWORD) P_tryuser));
}
// LOGON
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_LOGON,
&P_logon );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = NameCheck(&P_logon, NAMETYPE_USER, rep_LOGON);
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" LOGON = %ws \n", P_logon));
}
// PASSWORD
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_PASSWD,
&P_passwd );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = NameCheck(&P_passwd, NAMETYPE_PASSWORD, rep_PASSWD);
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" PASSWORD = %ws \n", P_passwd));
}
// RANDOM
ApiStatus = GetParameter(argc,
argv,
ConfigHandle,
rep_RANDOM,
&ParmStrValue );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
ApiStatus = DwordCheck(ParmStrValue,
MIN_RANDOM, MAX_RANDOM, rep_RANDOM, &P_random);
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
IF_DEBUG(REPL) { // debug code
NetpKdPrint((" RANDOM = 0x%lx \n", P_random));
}
}
return( NO_ERROR );
}
DBGSTATIC NET_API_STATUS
GetParameter(
IN DWORD argc,
IN LPTSTR argv[],
IN LPNET_CONFIG_HANDLE ConfigHandle,
IN LPTSTR SwitchName,
IN OUT LPWSTR * ParmValue
)
/*++
Routine Description :
Read a parameter from nt.cfg and from command line and return
appropriate value.
Arguments :
argc, argv : command line
ConfigHandle : handle to our section of config data
SwitchName : name of the paremeter
Return Value :
return NO_ERROR if successfully retrive the requested parameter and
ParmValue is set appropriately.
return other values if it can't retrive the parameter.
ReplFinish is called to terminate service.
--*/
{
NET_API_STATUS ApiStatus;
LPTSTR KeywordT;
LPTSTR ValueT;
LPWSTR ValueW;
ApiStatus = GetCmdValue(argc, argv, SwitchName, &ValueW );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
}
if (ValueW != NULL) {
*ParmValue = ValueW;
return( NO_ERROR );
}
//
// No value given in command line so read config data.
//
NetpAssert( SwitchName[0] == TCHAR_FWDSLASH );
KeywordT = & SwitchName[1];
ApiStatus = NetpGetConfigValue(
ConfigHandle,
KeywordT,
& ValueT); // Must be freed by NetApiBufferFree().
if (ApiStatus != NO_ERROR) {
//
// this parameter does not have an entry in nt.cfg and it is
// not defined in command line. However we return NO_ERROR and
// leaving the parameter value to default value the program
// assumed.
//
NetpAssert( ValueT == NULL );
return( NO_ERROR );
}
NetpAssert( ValueT != NULL );
//
// Give caller a copy of the value we found in config data.
//
ValueW = NetpAllocWStrFromTStr( ValueT ); // will check result below
NetpMemoryFree( ValueT );
if (ValueW == NULL) {
NetpKdPrint(( "[REPL] GetParameter: out of memory.\n" ));
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_RESOURCE, SERVICE_UIC_M_MEMORY),
NULL);
return( ERROR_NOT_ENOUGH_MEMORY );
}
*ParmValue = ValueW;
return( NO_ERROR );
} // GetParameter
DBGSTATIC NET_API_STATUS
GetCmdValue(
IN DWORD argc,
IN LPTSTR argv[],
IN LPTSTR SwitchName,
IN OUT LPWSTR * ParmValue
)
/*++
Routine Description :
read a parameter from command line
Arguments :
argc, argv : command line parameters
SwitchName : parameter name
Return Value :
return NO_ERROR if successfully retrive the requested parameter and
ParmValue is set appropriately.
return ERROR_INVALID_PARAMETER if it can't retrive the parameter.
ReplFinish is called to terminate service.
--*/
{
NET_API_STATUS ApiStatus = NO_ERROR; // innocent until proven guilty
LPTSTR SepaPtr;
DWORD i;
*ParmValue = NULL;
NetpAssert( SwitchName[0] == TCHAR_FWDSLASH );
for(i = 0; i < argc; i++) {
SepaPtr = STRCHR(argv[i], (TCHAR) ':');
if (SepaPtr == NULL) {
ReplConfigReportBadParmValue( SwitchName, NULL );
ApiStatus = ERROR_INVALID_PARAMETER;
break;
}
if (STRNICMP(argv[i], SwitchName, (SepaPtr - argv[i])) == 0) {
*ParmValue = NetpAllocWStrFromTStr( SepaPtr + 1 ); // skip colon.
if(*ParmValue == NULL) {
NetpKdPrint(( "[REPL] GetCmdValue: out of memory.\n" ));
ReplFinish(
SERVICE_UIC_CODE(
SERVICE_UIC_RESOURCE,
SERVICE_UIC_M_MEMORY),
NULL);
ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
break;
}
break;
}
}
IF_DEBUG(REPL) {
NetpKdPrint(( "GetCmdValue: returning " FORMAT_API_STATUS
" while searching for '" FORMAT_LPTSTR "',\n",
ApiStatus, SwitchName ));
NetpKdPrint(( " *ParmValue = " FORMAT_LPVOID ".\n",
(LPVOID) *ParmValue));
}
return( ApiStatus );
}
DBGSTATIC NET_API_STATUS
PathCheck(
IN OUT LPWSTR * Path,
IN DWORD TypeWanted,
IN LPTSTR SwitchName
)
/*++
Routine Description :
check the syntax of the given path name and existance of that path.
Arguments :
Path : path name to test. (This will be freed by this routine, and set to
point to a new alloc'ed canonicalized path.)
TypeWanted : path type to test
SwitchName : name of switch associated with this path.
Return Value :
NET_API_STATUS (e.g. ERROR_INVALID_PARAMETER if error in *Path)
NOTE : it frees the original path buffer.
NOTE: This routine also changes the current directory.
--*/
{
NET_API_STATUS ApiStatus;
DWORD ActualType = 0;
TCHAR CanonPathT[MAX_PATH]; // BUGBUG do we want +1 here?
LPWSTR CanonPathW;
LPTSTR UncanonPathT; // Input path as TCHARs.
LPWSTR UncanonPathW;
NetpAssert( Path != NULL );
NetpAssert( *Path != NULL );
UncanonPathW = *Path;
UncanonPathT = NetpAllocTStrFromWStr( UncanonPathW );
if (UncanonPathT == NULL) {
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_RESOURCE, SERVICE_UIC_M_MEMORY),
NULL);
return( ERROR_NOT_ENOUGH_MEMORY );
}
ApiStatus = I_NetPathCanonicalize(
NULL,
UncanonPathT,
CanonPathT,
sizeof(CanonPathT),
NULL,
&ActualType,
0);
IF_DEBUG(REPL) {
NetpKdPrint(( "[Repl] PathCheck: TypeWanted is " FORMAT_DWORD " for "
FORMAT_LPWSTR " and real type is " FORMAT_DWORD ".\n",
TypeWanted, *Path, ActualType ));
NetpKdPrint(( "[REPL] PathCheck: ApiStatus is " FORMAT_API_STATUS
".\n", ApiStatus ));
}
NetpMemoryFree( UncanonPathT );
//
// Check the type of the input.
//
if (TypeWanted == ITYPE_PATH_ABSD) {
if ((ApiStatus != NO_ERROR) || (ActualType != ITYPE_PATH_ABSD)) {
ReplConfigReportBadParmValue( SwitchName, *Path );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
} else {
return( ERROR_INVALID_PARAMETER );
}
}
} else {
NetpAssert( TypeWanted == ITYPE_PATH_RELND );
if ((ApiStatus != NO_ERROR) ||
((ActualType != ITYPE_PATH_ABSD) &&
(ActualType != ITYPE_PATH_RELND))) {
ReplConfigReportBadParmValue( SwitchName, *Path );
if (ApiStatus != NO_ERROR) {
return( ApiStatus );
} else {
return( ERROR_INVALID_PARAMETER );
}
}
}
//
// Arrange to pass back the canonicalized version of input path.
//
NetpMemoryFree( UncanonPathW );
if (ActualType == ITYPE_PATH_ABSD) {
CanonPathW = NetpAllocWStrFromTStr( CanonPathT );
if (CanonPathW == NULL) {
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_RESOURCE, SERVICE_UIC_M_MEMORY),
NULL);
return( ERROR_NOT_ENOUGH_MEMORY );
}
} else {
//
// BUGBUG: Can't get canon relative path, 'cos bug in
// I_NetPathCanonicalize insists on add current directory to it.
// But we don't need this for the time being (or ever?).
//
NetpAssert( FALSE );
}
NetpAssert( CanonPathW != NULL );
*Path = CanonPathW;
//
// Make sure the path is valid path and it exists.
//
if (!SetCurrentDirectoryW(CanonPathW)) {
ReplFinish( SERVICE_UIC_CODE( SERVICE_UIC_SYSTEM, 0), NULL);
return( ERROR_DIRECTORY ); // BUGBUG: Is there a better error code?
}
return( NO_ERROR );
} // PathCheck
DBGSTATIC NET_API_STATUS
ListCheck(
IN LPWSTR list,
IN LPTSTR SwitchName
)
/*++
Routine Description :
check a name list.
Arguments :
list : name list
SwitchName : name of switch associated with this parameter.
Return Value :
return NO_ERROR if the list is OK
CmdValue is set appropriately.
return error code if not, ReplFinish is called to terminate service.
Note :
1. does return from this routine if error
2. Canonicalize the export name list, Really just making sure
no major errors here, master process will do actual work anyway.
--*/
{
#if UNICODE
WCHAR WorkBuf[MAX_PATH * MAX_REPL_NAMELIST];
#else // UNICODE
CHAR WorkBuf[MAX_PATH * MAX_REPL_NAMELIST];
LPSTR AnsiName;
#endif
DWORD list_count;
NET_API_STATUS NetStatus;
#ifdef UNICODE
NetStatus = I_NetListCanonicalize(NULL,
list,
LIST_DELIMITER_STR_UI,
WorkBuf,
sizeof(WorkBuf) ,
&list_count,
NULL,
0,
(NAMETYPE_COMPUTER |
OUTLIST_TYPE_API |
INLC_FLAGS_MULTIPLE_DELIMITERS |
INLC_FLAGS_CANONICALIZE
));
if((NetStatus != NO_ERROR) ||
(list_count > MAX_REPL_NAMELIST)) {
ReplConfigReportBadParmValue( SwitchName, list );
if (NetStatus != NO_ERROR) {
return( NetStatus );
} else {
return( ERROR_INVALID_PARAMETER );
}
}
#else // UNICODE
AnsiName = NetpAllocStrFromWStr(list);
if(AnsiName == NULL) {
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_RESOURCE, SERVICE_UIC_M_MEMORY),
NULL);
return( ERROR_NOT_ENOUGH_MEMORY );
}
NetStatus = I_NetListCanonicalize(NULL,
AnsiName,
LIST_DELIMITER_STR_UI,
WorkBuf,
sizeof(WorkBuf) ,
&list_count,
NULL,
0,
(NAMETYPE_COMPUTER |
OUTLIST_TYPE_API |
INLC_FLAGS_MULTIPLE_DELIMITERS |
INLC_FLAGS_CANONICALIZE
));
NetpMemoryFree(AnsiName);
if((NetStatus != NO_ERROR) ||
(list_count > MAX_REPL_NAMELIST)) {
ReplConfigReportBadParmValue( SwitchName, list );
if (NetStatus != NO_ERROR) {
return( NetStatus );
} else {
return( ERROR_INVALID_PARAMETER );
}
}
#endif // UNICODE
return( NO_ERROR );
}
DBGSTATIC NET_API_STATUS
DwordCheck(
IN LPWSTR StrValue OPTIONAL,
IN DWORD Min,
IN DWORD Max,
IN LPTSTR SwitchName,
IN OUT LPDWORD DwordValue
)
/*++
Routine Description :
convert a string parameter to DWORD parameter. Also check the range
of parameter.
Arguments :
StrValue : WCHAR string (or NULL if no value given)
Min : minimum value of the parameter.
Max : maximum value of the parameter.
SwitchName : name of switch associated with this parameter.
Return Value :
return NO_ERROR if successfully convert and set dword value.
return error code if not, ReplFinish is called to terminate service.
NOTE : it frees the storage of the parameter buffer.
--*/
{
DWORD value;
if (StrValue != NULL) {
*DwordValue = 0;
value = (DWORD) wtol(StrValue);
NetpMemoryFree(StrValue);
} else {
value = *DwordValue;
}
if((value < Min) || (value > Max)) {
ReplConfigReportBadParmValue( SwitchName, StrValue );
return( ERROR_INVALID_PARAMETER );
}
*DwordValue = value;
return( NO_ERROR );
}
DBGSTATIC NET_API_STATUS
YesNoCheck(
IN LPWSTR StrValue OPTIONAL,
IN LPTSTR SwitchName,
IN OUT LPBOOL Value
)
/*++
Routine Description :
check YES/NO type parameter.
Arguments :
StrValue : parameter value.
SwitchName : name of switch associated with this parameter.
Return Value :
return NO_ERROR if successfully set yes/no value.
return error code if not, ReplFinish is called to terminate service.
--*/
{
if (StrValue != NULL) {
if(wcsncmpi(StrValue, L"YES", wcslen(StrValue)) == 0) {
NetpMemoryFree(StrValue);
*Value = TRUE;
return (NO_ERROR);
}
if(wcsncmpi(StrValue, L"NO", wcslen(StrValue)) == 0) {
NetpMemoryFree(StrValue);
*Value = FALSE;
return (NO_ERROR);
}
ReplConfigReportBadParmValue( SwitchName, StrValue );
return (ERROR_INVALID_PARAMETER);
} else {
return (NO_ERROR); // Leave default set.
}
/*NOTREACHED*/
}
DBGSTATIC NET_API_STATUS
NameCheck(
IN OUT LPWSTR * Name,
IN DWORD Type,
IN LPTSTR SwitchName
)
/*++
Routine Description :
check NAME type parameter.
Arguments :
Name : name value
Type : name type
SwitchName : name of switch associated with this parameter.
Return Value :
return NO_ERROR if successfully checks the name value.
return error code if not, ReplFinish is called to terminate service.
--*/
{
#ifdef UNICODE
LPWSTR CanonName;
#else // UNICODE
LPSTR CanonName;
LPSTR AnsiName;
#endif
NET_API_STATUS NetStatus;
if(*Name != NULL) {
if((Type == NAMETYPE_USER) && ((*Name)[0] == L'\0')) {
ReplConfigReportBadParmValue( SwitchName, *Name );
return( ERROR_INVALID_PARAMETER );
}
#ifdef UNICODE
CanonName = NetpMemoryAllocate((UNLEN + 1) * sizeof(WCHAR));
if(CanonName == NULL) {
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_RESOURCE, SERVICE_UIC_M_MEMORY),
NULL);
return( ERROR_NOT_ENOUGH_MEMORY );
}
NetStatus = I_NetNameCanonicalize(NULL,
*Name,
CanonName,
(UNLEN + 1) * sizeof(WCHAR),
Type,
0);
if(NetStatus != NO_ERROR) {
NetpMemoryFree(CanonName);
ReplConfigReportBadParmValue( SwitchName, *Name );
return( NetStatus );
}
NetpMemoryFree(*Name);
*Name = CanonName;
#else //UNICODE
AnsiName = NetpAllocStrFromWStr(*Name);
CanonName = NetpMemoryAllocate(UNLEN + 1);
if((AnsiName == NULL) || (CanonName == NULL)) {
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_RESOURCE, SERVICE_UIC_M_MEMORY),
NULL);
return( ERROR_NOT_ENOUGH_MEMORY );
}
NetStatus = I_NetNameCanonicalize(NULL,
AnsiName,
CanonName,
(UNLEN + 1),
Type,
0);
NetpMemoryFree(AnsiName);
if(NetStatus != NO_ERROR) {
NetpMemoryFree(CanonName);
ReplConfigReportBadParmValue( SwitchName, *Name );
return( NetStatus );
}
NetpMemoryFree(*Name);
*Name = NetpAllocWStrFromStr(CanonName);
NetpMemoryFree(CanonName);
if(*Name == NULL) {
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_RESOURCE, SERVICE_UIC_M_MEMORY),
NULL);
return( NetStatus );
}
#endif
}
return( NO_ERROR );
}
// Routine to report a bad parm value.
// There are two different versions of this routine,
// in client/report.c and server/parse.c [actually now server/error.c]
// client/report.c is callable whether or not service is started.
// server/parse.c only runs when service is starting; it talks to the service
// controller.
VOID
ReplConfigReportBadParmValue(
IN LPTSTR SwitchName,
IN LPWSTR TheValue OPTIONAL
)
{
UNREFERENCED_PARAMETER( SwitchName );
NetpAssert( SwitchName != NULL );
IF_DEBUG(REPL) {
NetpKdPrint(( "[REPL] Bad value to " FORMAT_LPTSTR " switch.\n",
SwitchName ));
}
ReplFinish(
SERVICE_UIC_CODE( SERVICE_UIC_BADPARMVAL, 0),
TheValue);
} // ReplConfigReportBadParmValue
VOID
InitParseData(
VOID
)
{
def_P_repl = DEFAULT_REPL;
def_P_exppath = DEFAULT_EXPPATH;
def_P_imppath = DEFAULT_IMPPATH;
def_P_explist = DEFAULT_EXPLIST;
def_P_implist = DEFAULT_IMPLIST;
def_P_logon = DEFAULT_LOGON;
def_P_passwd = DEFAULT_PASSWD;
P_repl = def_P_repl;
P_exppath = def_P_exppath;
P_imppath = def_P_imppath;
P_explist = def_P_explist;
P_implist = def_P_implist;
P_logon = def_P_logon;
P_passwd = def_P_passwd;
P_tryuser = DEFAULT_TRYUSER;
P_sync = DEFAULT_SYNC;
P_pulse = DEFAULT_PULSE;
P_guard = DEFAULT_GUARD;
P_random = DEFAULT_RANDOM;
ReplGlobalRole = REPL_ROLE_IMPORT;
}
VOID
FreeParseData(
VOID
)
{
// free up the heap memory
if( P_repl != def_P_repl) {
NetpMemoryFree(P_repl);
}
if( P_exppath != def_P_exppath ) {
NetpMemoryFree(P_exppath);
}
if( P_imppath != def_P_imppath ) {
NetpMemoryFree(P_imppath);
}
if( P_explist != def_P_explist ) {
NetpMemoryFree(P_explist);
}
if( P_implist != def_P_implist ) {
NetpMemoryFree(P_implist);
}
if( P_logon != def_P_logon ) {
NetpMemoryFree(P_logon);
}
if( P_passwd != def_P_passwd ) {
NetpMemoryFree(P_passwd);
}
}
#endif // 0 - entire file is obsolete.