/*++ Copyright (c) 1991-1993 Microsoft Corporation Module Name: ImpStub.c Abstract: Client stubs of the replicator service import directory APIs. Author: John Rogers (JohnRo) 17-Dec-1991 Environment: User Mode - Win32 Revision History: 17-Dec-1991 JohnRo Created dummy file. 17-Dec-1991 JohnRo Actually include my header file (LmRepl.h) so we can test against it. 17-Jan-1992 JohnRo Wrote stubs for first 3 RPCable APIs. 20-Jan-1992 JohnRo Added import APIs, config APIs, and rest of export APIs. 27-Jan-1992 JohnRo Split stubs into 3 files: ReplStub.c, ImpStub.c, and ExpStub.c. Changed to use LPTSTR etc. Added handling of getinfo and setinfo APIs when service isn't started. Tell NetRpc.h macros that we need replicator service. 05-Feb-1992 JohnRo Added debug messages when service is not started. 13-Feb-1992 JohnRo Moved section name equates to ConfName.h. 21-Feb-1992 JohnRo Make NetReplImportDir{Del,Enum,Get,Lock,Unlock} work w/o svc running. Fixed usage of union/container. 21-Feb-1992 JohnRo Changed ImportDirBuildApiRecord() so master name is not a UNC name. 27-Feb-1992 JohnRo Preserve state from last time service was running. Changed state not started to state never replicated. 15-Mar-1992 JohnRo Update registry with new values. 23-Mar-1992 JohnRo Fixed enum when service is running. 09-Jul-1992 JohnRo RAID 10503: srv mgr: repl dialog doesn't come up. Avoid compiler warnings. Use PREFIX_ equates. 27-Jul-1992 JohnRo RAID 2274: repl svc should impersonate caller. 09-Nov-1992 JohnRo RAID 7962: Repl APIs in wrong role kill svc. Fix remote repl admin. 02-Apr-1993 JohnRo Use NetpKdPrint() where possible. Made changes suggested by PC-LINT 5.0 Removed some obsolete comments about retrying APIs. --*/ // These must be included first: #include // IN, DWORD, etc. #include // NET_API_STATUS, etc. #include // Needed by . #include // Needed by . #include // Needed by . // These may be included in any order: #include // ReplIsDirNameValid(). #include // ImportDirIsApiRecordValid(), etc. #include // My prototypes, etc. #include // NERR_ and ERROR_ equates, NO_ERROR. #include // SERVICE_ name equates. #include // NetpSetParmError() macro. #include // NET_REMOTE macros. #include // PREFIX_ equates. #include // MIDL-generated NetrRepl prototypes. #include // GENERIC_INFO_CONTAINER, etc. NET_API_STATUS NET_API_FUNCTION NetReplImportDirAdd ( IN LPCWSTR UncServerName OPTIONAL, IN DWORD Level, IN const LPBYTE Buf, OUT LPDWORD ParmError OPTIONAL // Set implicitly by NetpSetParmError(). ) { NET_API_STATUS ApiStatus; LPIMPORT_CONTAINER ApiUnion = (LPVOID) &Buf; NET_REMOTE_TRY_RPC // // Try RPC (local or remote) version of API. // ApiStatus = NetrReplImportDirAdd( (LPWSTR)UncServerName, Level, ApiUnion, ParmError); NET_REMOTE_RPC_FAILED("NetReplImportDirAdd", UncServerName, ApiStatus, NET_REMOTE_FLAG_NORMAL, SERVICE_REPL ) // // No downlevel version to call // ApiStatus = ERROR_NOT_SUPPORTED; NET_REMOTE_END if (ApiStatus == NERR_ServiceNotInstalled) { LPREPL_IDIR_INFO_0 ApiRecord; // level 0 by definition IF_DEBUG(DLLSTUB) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirAdd: running w/o service.\n" )); } // // Check for caller errors. // NetpSetParmError( PARM_ERROR_UNKNOWN ); // Assume error until proven... if (Level != 0) { return (ERROR_INVALID_LEVEL); } NetpAssert( ApiUnion != NULL ); if ((ApiUnion->Info0) == NULL) { return (ERROR_INVALID_PARAMETER); } ApiRecord = ApiUnion->Info0; // level 0 by definition NetpAssert( ApiRecord != NULL ); if ( !ReplIsDirNameValid(ApiRecord->rpid0_dirname) ) { NetpSetParmError( 1 ); // Error in first field in ApiRecord. return (ERROR_INVALID_PARAMETER); } // Make sure there is no existing record for this directory. if (ImportDirConfigDataExists( (LPWSTR)UncServerName, ApiRecord->rpid0_dirname )) { return (ERROR_ALREADY_EXISTS); } // Write the new or revised data. ApiStatus = ImportDirWriteConfigData ( (LPWSTR)UncServerName, ApiRecord->rpid0_dirname, REPL_STATE_NEVER_REPLICATED, NULL, // no master. (DWORD) 0, // last update time, secs since 1970. (DWORD) 0, // lock count (DWORD) 0 ); // time of first lock, secs since 1970. if (ApiStatus == NO_ERROR) { // // Everything went OK. Tell caller. // NetpSetParmError( PARM_ERROR_NONE ); } } return (ApiStatus); } // NetReplImportDirAdd NET_API_STATUS NET_API_FUNCTION NetReplImportDirDel ( IN LPCWSTR UncServerName OPTIONAL, IN LPCWSTR DirName ) { NET_API_STATUS ApiStatus; NET_REMOTE_TRY_RPC // // Try RPC (local or remote) version of API. // ApiStatus = NetrReplImportDirDel( (LPWSTR)UncServerName, (LPWSTR)DirName); NET_REMOTE_RPC_FAILED("NetReplImportDirDel", UncServerName, ApiStatus, NET_REMOTE_FLAG_NORMAL, SERVICE_REPL ) // // No downlevel version to call // ApiStatus = ERROR_NOT_SUPPORTED; NET_REMOTE_END // // Handle API when service isn't running... // if (ApiStatus == NERR_ServiceNotInstalled) { IF_DEBUG(DLLSTUB) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirDel: processing w/o svc.\n" )); } // // Check for caller errors. // if (DirName == NULL) { return (ERROR_INVALID_PARAMETER); } IF_DEBUG(DLLSTUB) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirDel: deleting API record for '" FORMAT_LPTSTR "'...\n", DirName )); } if ( !ReplIsDirNameValid((LPWSTR)DirName) ) { return (ERROR_INVALID_PARAMETER); } if (! ImportDirConfigDataExists( (LPWSTR)UncServerName, (LPWSTR)DirName )) { return (NERR_UnknownDevDir); } // // Write config data for this import directory. // ApiStatus = ImportDirDeleteConfigData( (LPWSTR)UncServerName, (LPWSTR)DirName ); IF_DEBUG(DLLSTUB) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirDel: done deleting API record, " "API status is " FORMAT_API_STATUS ".\n", ApiStatus )); } } return ApiStatus; } // NetReplImportDirDel NET_API_STATUS NET_API_FUNCTION NetReplImportDirEnum ( IN LPCWSTR UncServerName OPTIONAL, IN DWORD Level, OUT LPBYTE * BufPtr, IN DWORD PrefMaxSize, OUT LPDWORD EntriesRead, OUT LPDWORD TotalEntries, IN OUT LPDWORD ResumeHandle OPTIONAL ) { NET_API_STATUS ApiStatus; GENERIC_INFO_CONTAINER GenericInfoContainer; GENERIC_ENUM_STRUCT InfoStruct; GenericInfoContainer.Buffer = NULL; GenericInfoContainer.EntriesRead = 0; InfoStruct.Container = &GenericInfoContainer; InfoStruct.Level = Level; *BufPtr = NULL; // Must be NULL so RPC knows to fill it in. NET_REMOTE_TRY_RPC // // Try RPC (local or remote) version of API. // ApiStatus = NetrReplImportDirEnum( (LPWSTR)UncServerName, // Level, (LPIMPORT_ENUM_STRUCT) (LPVOID) &InfoStruct, PrefMaxSize, // EntriesRead, TotalEntries, ResumeHandle); if ((ApiStatus == NERR_Success) || (ApiStatus == ERROR_MORE_DATA)) { *BufPtr = (LPBYTE) GenericInfoContainer.Buffer; *EntriesRead = GenericInfoContainer.EntriesRead; } NET_REMOTE_RPC_FAILED("NetReplImportDirEnum", UncServerName, ApiStatus, NET_REMOTE_FLAG_NORMAL, SERVICE_REPL ) // // No downlevel version to call // ApiStatus = ERROR_NOT_SUPPORTED; NET_REMOTE_END // // Handle service not running by reading config data directly. // if (ApiStatus == NERR_ServiceNotInstalled) { IF_DEBUG(DLLSTUB) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirEnum: processing w/o svc.\n" )); } NetpSetOptionalArg( ResumeHandle, 0 ); ApiStatus = ImportDirEnumApiRecords( (LPWSTR)UncServerName, Level, BufPtr, PrefMaxSize, EntriesRead, TotalEntries ); } return ApiStatus; } // NetReplImportDirEnum NET_API_STATUS NET_API_FUNCTION NetReplImportDirGetInfo ( IN LPCWSTR UncServerName OPTIONAL, IN LPCWSTR DirName, IN DWORD Level, OUT LPBYTE * BufPtr ) { NET_API_STATUS ApiStatus; *BufPtr = NULL; // Must be NULL so RPC knows to fill it in. NET_REMOTE_TRY_RPC IF_DEBUG( DLLSTUB ) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirGetInfo: union at " FORMAT_LPVOID ".\n", (LPVOID) BufPtr )); } // // Try RPC (local or remote) version of API. // ApiStatus = NetrReplImportDirGetInfo( (LPWSTR)UncServerName, (LPWSTR)DirName, Level, (LPIMPORT_CONTAINER) (LPVOID) BufPtr); NET_REMOTE_RPC_FAILED("NetReplImportDirGetInfo", UncServerName, ApiStatus, NET_REMOTE_FLAG_NORMAL, SERVICE_REPL ) // // No downlevel version to call // ApiStatus = ERROR_NOT_SUPPORTED; NET_REMOTE_END if (ApiStatus == NERR_ServiceNotInstalled) { IF_DEBUG(DLLSTUB) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirGetInfo: processing w/o svc.\n" )); } ApiStatus = ImportDirGetApiRecord( (LPWSTR)UncServerName, (LPWSTR)DirName, Level, BufPtr ); } return ApiStatus; } // NetReplImportDirGetInfo NET_API_STATUS NET_API_FUNCTION NetReplImportDirLock ( IN LPCWSTR UncServerName OPTIONAL, IN LPCWSTR DirName ) { NET_API_STATUS ApiStatus; NET_REMOTE_TRY_RPC // // Try RPC (local or remote) version of API. // ApiStatus = NetrReplImportDirLock( (LPWSTR)UncServerName, (LPWSTR)DirName); NET_REMOTE_RPC_FAILED("NetReplImportDirLock", UncServerName, ApiStatus, NET_REMOTE_FLAG_NORMAL, SERVICE_REPL ) // // No downlevel version to call // ApiStatus = ERROR_NOT_SUPPORTED; NET_REMOTE_END if (ApiStatus == NERR_ServiceNotInstalled) { IF_DEBUG(DLLSTUB) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirLock: processing w/o svc.\n" )); } ApiStatus = ImportDirLockInRegistry( (LPWSTR)UncServerName, (LPWSTR)DirName ); } return ApiStatus; } // NetReplImportDirLock NET_API_STATUS NET_API_FUNCTION NetReplImportDirUnlock ( IN LPCWSTR UncServerName OPTIONAL, IN LPCWSTR DirName, IN DWORD UnlockForce ) { NET_API_STATUS ApiStatus; NET_REMOTE_TRY_RPC // // Try RPC (local or remote) version of API. // ApiStatus = NetrReplImportDirUnlock( (LPWSTR)UncServerName, (LPWSTR)DirName, UnlockForce); NET_REMOTE_RPC_FAILED("NetReplImportDirUnlock", UncServerName, ApiStatus, NET_REMOTE_FLAG_NORMAL, SERVICE_REPL ) // // No downlevel version to call // ApiStatus = ERROR_NOT_SUPPORTED; NET_REMOTE_END if (ApiStatus == NERR_ServiceNotInstalled) { IF_DEBUG(DLLSTUB) { NetpKdPrint(( PREFIX_REPL "NetReplImportDirUnlock: processing w/o svc.\n" )); } ApiStatus = ImportDirUnlockInRegistry( (LPWSTR)UncServerName, (LPWSTR)DirName, UnlockForce ); } return ApiStatus; } // NetReplImportDirUnlock