/*++ Copyright (c) 1992-1993 Microsoft Corporation Module Name: ImpBuild.c Abstract: This file contains ImportDirBuildApiRecord. This is used by NetrReplImportDirGetInfo and NetrReplImportDirEnum. Author: John Rogers (JohnRo) 08-Jan-1992 Environment: Portable to any flat, 32-bit environment. (Uses Win32 typedefs.) Requires ANSI C extensions: slash-slash comments, long external names. Notes: This code assumes that the import dir info levels are subsets of each other. Revision History: 08-Jan-1992 JohnRo Created. 24-Jan-1992 JohnRo Changed to use LPTSTR etc. 27-Jan-1992 JohnRo Changed interface to allow use when service is not running. 21-Feb-1992 JohnRo Fixed bug checking state parameter. UncMaster parm is optional. Added check of UncMaster validity. Undid redundant checks of Buffer (3 of them!) 21-Feb-1992 JohnRo Changed ImportDirBuildApiRecord() so master name is not a UNC name. 22-Feb-1992 JohnRo Made changes suggested by PC-LINT. 26-Feb-1992 JohnRo Check lock fields for validity. API records now contain timestamps instead of elapsed times. Added assertion of valid record at end. 25-Mar-1992 JohnRo Avoid obsolete state values. 27-Mar-1992 JohnRo Allow MasterName to point to a null char. 28-Jul-1992 JohnRo RAID 2274: repl svc should impersonate caller. Added debug output of structure after we build it. 30-Apr-1993 JohnRo Use NetpKdPrint() where possible. --*/ // These must be included first: #include // IN, VOID, LPTSTR, etc. #include // NET_API_STATUS. #include // ReplIsIntegrityValid(), IF_DEBUG(), SLASH_SLASH, etc. // These can be in any order: #include // POINTER_IS_ALIGNED(), ALIGN_TCHAR. #include // ReplIsDirNameValid(). #include // My prototype, ImportDirIsLevelValid(). #include // LPREPL_IDIR_INFO_1, REPL_EXTENT_ stuff, etc. #include // NetpIsComputerNameValid(). #include // NetpAssert(), NetpKdPrint(), etc. #include // PREFIX_ equates. #include // STRLEN(), TCHAR_EOS, etc. #include // ERROR_ equates, NO_ERROR. NET_API_STATUS ImportDirBuildApiRecord ( IN DWORD Level, IN LPTSTR DirName, IN DWORD State, IN LPTSTR MasterName OPTIONAL, // computer name (not UNC). IN DWORD TimeOfLastUpdate, // Seconds since 1970. IN DWORD LockCount, IN DWORD TimeOfFirstLock, // Seconds since 1970. OUT LPVOID Buffer, IN OUT LPBYTE *StringLocation // Points just past top of data. ) { LPREPL_IDIR_INFO_1 ApiRecord = Buffer; // superset info level LPTSTR StringDest; DWORD StringLength; NetpAssert( StringLocation != NULL); NetpAssert( *StringLocation != NULL); IF_DEBUG( IMPAPI ) { NetpKdPrint(( PREFIX_REPL "ImportDirBuildApiRecord: building record at " FORMAT_LPVOID ", *str loc is " FORMAT_LPVOID ".\n", (LPVOID) Buffer, (LPVOID) *StringLocation )); } if ( (MasterName != NULL) && ((*MasterName) == TCHAR_EOS) ) { MasterName = NULL; } // // Check for caller errors. // if ( ! ReplIsDirNameValid( DirName ) ) { return (ERROR_INVALID_DATA); } else if (Buffer == NULL) { return (ERROR_INVALID_PARAMETER); } else if ( !ReplIsStateValid( State ) ) { return (ERROR_INVALID_DATA); } else if ( !ImportDirIsLevelValid( Level ) ) { return (ERROR_INVALID_LEVEL); } else if ((MasterName!=NULL) && !NetpIsComputerNameValid(MasterName)) { return (ERROR_INVALID_PARAMETER); } else if ( !ReplAreLockFieldsValid( LockCount, TimeOfFirstLock ) ) { return (ERROR_INVALID_PARAMETER); } // // First do subset common to both info levels. // StringLength = (DWORD) STRLEN( DirName ); NetpAssert( POINTER_IS_ALIGNED( *StringLocation, ALIGN_TCHAR ) ); StringDest = (LPTSTR) (LPVOID) (*StringLocation); StringDest -= (StringLength + 1); *StringLocation = (LPBYTE) (LPVOID) StringDest; ApiRecord->rpid1_dirname = StringDest; (void) STRCPY( StringDest, // dest DirName); // src // // Next do stuff only found in level 1. // if (Level > 0) { // // Do master name (only other string)... // if (MasterName != NULL) { StringLength = (DWORD) STRLEN( MasterName ) + 2; // Ch to UNC. NetpAssert( POINTER_IS_ALIGNED( *StringLocation, ALIGN_TCHAR ) ); StringDest = (LPTSTR) (LPVOID) (*StringLocation); StringDest -= (StringLength + 1); *StringLocation = (LPBYTE) (LPVOID) StringDest; ApiRecord->rpid1_mastername = StringDest; (void) STRCPY( StringDest, // dest SLASH_SLASH ); // src (void) STRCAT( StringDest, // dest MasterName); // src } else { ApiRecord->rpid1_mastername = NULL; } // // Now do simple stuff... // { ApiRecord->rpid1_state = State; } ApiRecord->rpid1_last_update_time = TimeOfLastUpdate; ApiRecord->rpid1_lockcount = LockCount; if (TimeOfFirstLock == 0) { ApiRecord->rpid1_locktime = 0; } else { ApiRecord->rpid1_locktime = TimeOfFirstLock; } } IF_DEBUG( IMPAPI ) { NetpKdPrint(( PREFIX_REPL "ImportDirBuildApiRecord: built structure:\n" )); NetpDbgDisplayReplImportDir( Level, Buffer ); } NetpAssert( ImportDirIsApiRecordValid( Level, ApiRecord, NULL ) ); return (NO_ERROR); }