summaryrefslogblamecommitdiffstats
path: root/private/net/svcdlls/repl/server/expget.c
blob: 62ad37bda74f4aaf0d39e324f03167a0a6645f06 (plain) (tree)




















































































































































































































                                                                                
/*++

Copyright (c) 1992-1993  Microsoft Corporation

Module Name:

    ExpGet.c

Abstract:

    This file contains NetrReplExportDirGetInfo.

Author:

    John Rogers (JohnRo) 08-Jan-1992

Environment:

    Runs under Windows NT.
    Requires ANSI C extensions: slash-slash comments, long external names.

Revision History:

    08-Jan-1992 JohnRo
        Created.
    15-Jan-1992 JohnRo
        Corrected name of this routine.
    20-Jan-1992 JohnRo
        Netr prototypes are now generated by MIDL and put in repl.h.
    20-Jan-1992 JohnRo
        Changed prototype to match MIDL requirements.
    28-Jan-1992 JohnRo
        Changed ExportDirAllocApiRecords() to allow arrays.
        Changed to use LPTSTR etc.
        Changed ExportDirBuildApiRecord's interface.
    23-Mar-1992 JohnRo
        Do a little more checking before we lock things.
    28-Jul-1992 JohnRo
        Added more debug output.
        Avoid compiler warnings.
    13-Nov-1992 JohnRo
        RAID 1537: Repl APIs in wrong role kill svc.
    02-Apr-1993 JohnRo
        Use NetpKdPrint() where possible.

--*/


// These must be included first:

#include <windef.h>             // IN, VOID, LPTSTR, etc.
#include <lmcons.h>             // NET_API_STATUS.
#include <repldefs.h>           // Needed by <master.h>.
#include <master.h>             // PMASTER_LIST_REC.
#include <rpc.h>                // Needed by <repl.h>.

// These can be in any order:

#include <dirname.h>            // ReplIsDirNameValid().
#include <expdir.h>             // ExportDirBuildApiRecord(), etc.
#include <lmerr.h>              // ERROR_ and NERR_ equates; NO_ERROR.
#include <masproto.h>           // GetMasterRec().
#include <netdebug.h>           // NetpAssert().
#include <netlock.h>            // ACQUIRE_LOCK_SHARED(), RELEASE_LOCK().
#include <prefix.h>     // PREFIX_ equates.
#include <repl.h>               // My prototype (in MIDL-generated .h file).
#include <replgbl.h>    // ReplConfigLock, ReplConfigRole.


NET_API_STATUS
NetrReplExportDirGetInfo (
    IN LPTSTR UncServerName OPTIONAL,
    IN LPTSTR DirName,
    IN DWORD Level,
    OUT LPEXPORT_CONTAINER BufPtr       // RPC container (union)
    )

/*++

Routine Description:

    Same as NetReplExportDirGetInfo.

Arguments:

    Same as NetReplExportDirGetInfo.

Return Value:

    Same as NetReplExportDirGetInfo.

--*/

{
    LPVOID ApiRecord = NULL;
    NET_API_STATUS ApiStatus;
    BOOL ConfigLocked = FALSE;
    BOOL ListLocked = FALSE;
    PMASTER_LIST_REC MasterRecord;
    LPVOID StringLocation;

    IF_DEBUG( EXPAPI ) {
        NetpKdPrint(( PREFIX_REPL
                "NetrReplExportDirGetInfo: union at " FORMAT_LPVOID ".\n",
                (LPVOID) BufPtr ));
    }

    //
    // Check for caller errors.
    //
    if (BufPtr == NULL) {
        return (ERROR_INVALID_PARAMETER);
    }

    BufPtr->Info0 = NULL;  // Don't confuse caller about possible alloc'ed data.

    if (ReplIsDirNameValid( DirName ) == FALSE) {
        return (ERROR_INVALID_PARAMETER);
    } else if ( !ExportDirIsLevelValid( Level, FALSE ) ) {  // no setinfo levels
        return (ERROR_INVALID_LEVEL);
    }

    //
    // Get a shared lock on config data so we can see if role includes export.
    //
    ACQUIRE_LOCK_SHARED( ReplConfigLock );
    ConfigLocked = TRUE;

    if ( !ReplRoleIncludesExport( ReplConfigRole ) ) {
        ApiStatus = ExportDirGetApiRecord (
                UncServerName,
                DirName,
                Level,
                (LPBYTE *) (LPVOID) & ApiRecord );
        goto Cleanup;
    }

    //
    // Get read-only lock on master list.
    //
    ACQUIRE_LOCK_SHARED( RMGlobalListLock );
    ListLocked = TRUE;

    //
    // Find the master record for this dir name.
    //
    MasterRecord = GetMasterRec( DirName );
    if (MasterRecord == NULL) {   // Not found.

        ApiStatus = NERR_UnknownDevDir;
        // Don't forget to release lock...

    } else {   // Found.

        //
        // Allocate the output area.
        // Compute size of output area (and check caller's Level too).
        //
        ApiStatus = ExportDirAllocApiRecords (
                Level,
                1,                      // only need one record.
                (LPBYTE *) & ApiRecord,
                (LPBYTE *) (LPVOID) & StringLocation ); // Points past data end.
        if (ApiStatus != NO_ERROR) {

            // ApiStatus is already set to return error to caller.
            // Don't forget to release lock...

        } else {
            NetpAssert( ApiRecord != NULL );

            //
            // Build ApiRecord!
            //
            ApiStatus = ExportDirBuildApiRecord (
                    Level,
                    DirName,
                    MasterRecord->integrity,
                    MasterRecord->extent,
                    MasterRecord->lockcount,
                    MasterRecord->time_of_first_lock,  // Secs since 1970.
                    ApiRecord,
                    (LPBYTE *) (LPVOID) & StringLocation);
            NetpAssert( ApiStatus == NO_ERROR );  // We checked all parms.

            // Don't forget to release lock...

        }

    }

Cleanup:

    //
    // Release locks and tell caller how everything went.
    //

    if (ListLocked) {
        RELEASE_LOCK( RMGlobalListLock );
    }

    if (ConfigLocked) {
        RELEASE_LOCK( ReplConfigLock );
    }

    if (ApiStatus == NO_ERROR) {
        NetpAssert( ApiRecord != NULL );
        NetpAssert( ExportDirIsApiRecordValid( Level, ApiRecord, NULL ) );
    }
    BufPtr->Info2 = (LPVOID) ApiRecord;
    return (ApiStatus);

}