#include #include #include #include #include #include #include #include #include #include #include #include #include "ReferralServerLog.hxx" // // logging specific includes // #include "apisupport.tmh" extern ULONG Flags; CRITICAL_SECTION DfsApiLock; BOOL DfsLockInitialized = FALSE; BOOL ServerListen = FALSE; #define DFS_API_START() \ EnterCriticalSection( &DfsApiLock ); \ _try \ { #define DFS_API_END() \ } _finally { \ LeaveCriticalSection( &DfsApiLock); \ } extern DFSSTATUS DfsEnum( IN LPWSTR DfsName, IN DWORD Level, IN DWORD PrefMaxLen, OUT LPBYTE *pBuffer, OUT LPDWORD pEntriesRead, IN OUT LPDWORD pResumeHandle); NET_API_STATUS DfsEnumEx( IN LPWSTR DfsName, IN DWORD Level, IN DWORD PrefMaxLen, IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum, IN OUT LPDWORD pResumeHandle); //+---------------------------------------------------------------------------- // // Function: NetrDfsManagerGetVersion // // Synopsis: Returns the version of this server side implementation. // // Arguments: None. // // Returns: The version number. // //----------------------------------------------------------------------------- DWORD NetrDfsManagerGetVersion() { DWORD Version = 4; return( Version ); } //+---------------------------------------------------------------------------- // // Function: NetrDfsAdd // Synopsis: // // Arguments: [DfsEntryPath] -- Entry Path of volume/link to be created, or // to which a replica should be added. // [ServerName] -- Name of server backing the volume. // [ShareName] -- Name of share on ServerName backing the volume. // [Comment] -- Comment associated with this volume, only used // when DFS_ADD_VOLUME is specified. // [Flags] -- If DFS_ADD_VOLUME, a new volume will be created. // If DFS_ADD_LINK, a new link to another Dfs will be // create. If 0, a replica will be added. // // Returns: [NERR_Success] -- Operation succeeded. // // Error other wise. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsAdd( IN LPWSTR DfsEntryPath, IN LPWSTR ServerName, IN LPWSTR ShareName, IN LPWSTR Comment, IN DWORD Flags) { NET_API_STATUS Status = ERROR_SUCCESS; DFS_TRACE_HIGH( API, "Net Dfs Add %ws %ws %ws\n", DfsEntryPath, ServerName, ShareName); DFS_API_START(); Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsAdd( DfsEntryPath, ServerName, ShareName, Comment, Flags ); } DFS_API_END(); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add %ws, Status 0x%x\n", DfsEntryPath, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsAdd2 // // Synopsis: Adds a volume/replica/link to this Dfs. // // Arguments: [DfsEntryPath] -- Entry Path of volume/link to be created, or // to which a replica should be added. // [DcName] -- Name of Dc to use // [ServerName] -- Name of server backing the volume. // [ShareName] -- Name of share on ServerName backing the volume. // [Comment] -- Comment associated with this volume, only used // when DFS_ADD_VOLUME is specified. // [Flags] -- If DFS_ADD_VOLUME, a new volume will be created. // If DFS_ADD_LINK, a new link to another Dfs will be // create. If 0, a replica will be added. // [ppRootList] -- On success, returns a list of roots that need to be // informed of the change in the DS object // // Returns: [NERR_Success] -- Operation succeeded. // // Erroroce otherwise. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsAdd2( IN LPWSTR DfsEntryPath, IN LPWSTR DcName, IN LPWSTR ServerName, IN LPWSTR ShareName, IN LPWSTR Comment, IN DWORD Flags, IN PDFSM_ROOT_LIST *ppRootList) { NET_API_STATUS Status = ERROR_SUCCESS; DFS_TRACE_HIGH( API, "Net Dfs Add2 %ws DC:%ws Server:%ws Share:%ws\n", DfsEntryPath, DcName, ServerName, ShareName); DFS_API_START(); // // For now, we dont use DC name or pprootlist. We will use // this once we implement domain dfs. // UNREFERENCED_PARAMETER( DcName ); UNREFERENCED_PARAMETER( ppRootList ); Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsAdd( DfsEntryPath, ServerName, ShareName, Comment, Flags ); } DFS_API_END(); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add2 %ws, Status 0x%x\n", DfsEntryPath, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsGetDcAddress // // Synopsis: Gets the DC to go to so that we can create an FtDfs object for // this server. // // Arguments: [ServerName] -- Name of server backing the volume. // [DcName] -- Dc to use // [IsRoot] -- TRUE if this server is a Dfs root, FALSE otherwise // [Timeout] -- Timeout, in sec, that the server will stay with this DC // // Returns: [NERR_Success] -- Operation succeeded. // // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsGetDcAddress( IN LPWSTR ServerName, IN OUT LPWSTR *DcName, IN OUT BOOLEAN *IsRoot, IN OUT ULONG *Timeout) { NET_API_STATUS Status = ERROR_SUCCESS; UNREFERENCED_PARAMETER(ServerName); // // Currently, not supported // if(DcName == NULL) { Status = ERROR_INVALID_PARAMETER; return Status; } *DcName = (LPWSTR)MIDL_user_allocate(4); if (*DcName == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { (*DcName)[0] = L' '; (*DcName)[1] = 0; } if(IsRoot) { *IsRoot = FALSE; } if(Timeout) { *Timeout = 1000; } return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsSetDcAddress // // Synopsis: Sets the DC to go to for the dfs blob // // Arguments: [ServerName] -- Name of server backing the volume. // [DcName] -- Dc to use // [Timeout] -- Time, in sec, to stay with that DC // // Returns: [NERR_Success] -- Operation succeeded. // // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsSetDcAddress( IN LPWSTR ServerName, IN LPWSTR DcName, IN ULONG Timeout, IN DWORD Flags) { UNREFERENCED_PARAMETER(ServerName); UNREFERENCED_PARAMETER(DcName); UNREFERENCED_PARAMETER(Timeout); UNREFERENCED_PARAMETER(Flags); // // Currently, not supported // return ERROR_SUCCESS; } //+---------------------------------------------------------------------------- // // Function: NetrDfsFlushFtTable // // Synopsis: Flushes an FtDfs entry from the FtDfs cache // // Arguments: [DcName] -- Dc to use // [FtDfsName] -- Name of FtDfs // // Returns: [NERR_Success] -- Operation succeeded. // // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsFlushFtTable( IN LPWSTR DcName, IN LPWSTR FtDfsName) { UNREFERENCED_PARAMETER(DcName); UNREFERENCED_PARAMETER(FtDfsName); // // This will NEVER be supported. // return ERROR_NOT_SUPPORTED; } //+---------------------------------------------------------------------------- // // Function: NetrDfsAddStdRoot // // Synopsis: Creates a new Std Dfs // // Arguments: [ServerName] -- Name of server backing the volume. // [RootShare] -- Name of share on ServerName backing the volume. // [Comment] -- Comment associated with this root. // [Flags] -- Flags for the operation // // Returns: [NERR_Success] -- Operation succeeded. // // [NERR_DfsInternalCorruption] -- An internal database // corruption was encountered while executing this // operation. // // [ERROR_OUTOFMEMORY] -- Out of memory condition. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsAddStdRoot( IN LPWSTR ServerName, IN LPWSTR RootShare, IN LPWSTR Comment, IN DWORD ApiFlags) { NET_API_STATUS Status = ERROR_SUCCESS; DFS_TRACE_HIGH( API, "Net Dfs Add Std Root Server:%ws, Share:%ws\n", ServerName, RootShare); DFS_API_START(); if (Flags & DFS_LOCAL_NAMESPACE) { ServerName = NULL; } // // Add a standalone root. // Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsAddStandaloneRoot( ServerName, RootShare, Comment, ApiFlags ); } DFS_API_END(); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add Std Root %ws\n", RootShare); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsAddStdRootForced // // Synopsis: Creates a new Std Dfs // // Arguments: [ServerName] -- Name of server backing the volume. // [RootShare] -- Name of share on ServerName backing the volume. // [Comment] -- Comment associated with this root. // [Share] -- drive:\dir behind the share // // Returns: [NERR_Success] -- Operation succeeded. // // [ERROR_OUTOFMEMORY] -- Out of memory condition. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsAddStdRootForced( IN LPWSTR ServerName, IN LPWSTR RootShare, IN LPWSTR Comment, IN LPWSTR Share) { UNREFERENCED_PARAMETER(ServerName); UNREFERENCED_PARAMETER(RootShare); UNREFERENCED_PARAMETER(Comment); UNREFERENCED_PARAMETER(Share); // // This will probably be never supported. // return ERROR_NOT_SUPPORTED; } //+---------------------------------------------------------------------------- // // Function: NetrDfsRemove (Obsolete) // // Synopsis: Deletes a volume/replica/link from the Dfs. // // Arguments: [DfsEntryPath] -- Entry path of the volume to operate on. // [ServerName] -- If specified, indicates the replica of the // volume to operate on. // [ShareName] -- If specified, indicates the share on the // server to operate on. // [Flags] -- Flags for the operation // // Returns: [NERR_Success] -- Operation successful. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsRemove( IN LPWSTR DfsEntryPath, IN LPWSTR ServerName, IN LPWSTR ShareName) { NET_API_STATUS Status = ERROR_SUCCESS; DFS_TRACE_HIGH( API, "Net Dfs remove %ws\n", DfsEntryPath); // // call DfsRemove to do this operation. // DFS_API_START(); Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsRemove( DfsEntryPath, ServerName, ShareName ); } DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove %ws, Status %x\n", DfsEntryPath, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsRemove2 // // Synopsis: Deletes a volume/replica/link from the Dfs. // // Arguments: [DfsEntryPath] -- Entry path of the volume to operate on. // [DcName] -- Name of Dc to use // [ServerName] -- If specified, indicates the replica of the // volume to operate on. // [ShareName] -- If specified, indicates the share on the // server to operate on. // [Flags] -- Flags for the operation // [ppRootList] -- On success, returns a list of roots that need to be // informed of the change in the DS object // // Returns: [NERR_Success] -- Operation successful. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsRemove2( IN LPWSTR DfsEntryPath, IN LPWSTR DcName, IN LPWSTR ServerName, IN LPWSTR ShareName, IN PDFSM_ROOT_LIST *ppRootList) { UNREFERENCED_PARAMETER(DcName); UNREFERENCED_PARAMETER(ppRootList); NET_API_STATUS Status = ERROR_SUCCESS; // // For now we ignore the DcName and rootlist, these are needed // when we implement dom dfs. // DFS_TRACE_HIGH( API, "Net Dfs remove2 %ws\n", DfsEntryPath); DFS_API_START( ); Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsRemove( DfsEntryPath, ServerName, ShareName ); } DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove2 %ws, Status %x\n", DfsEntryPath, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsRemoveStdRoot // // Synopsis: Deletes a Dfs root // // Arguments: [ServerName] -- The server to remove. // [RootShare] -- The Root share hosting the Dfs/FtDfs // [Flags] -- Flags for the operation // // Returns: [NERR_Success] -- Operation successful. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsRemoveStdRoot( IN LPWSTR ServerName, IN LPWSTR RootShare, IN DWORD Flags) { UNREFERENCED_PARAMETER(ServerName); UNREFERENCED_PARAMETER(Flags); NET_API_STATUS Status = ERROR_SUCCESS; DFS_TRACE_HIGH( API, "Net Dfs remove std root %ws\n", RootShare); DFS_API_START( ); Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsDeleteStandaloneRoot( ServerName, RootShare ); } DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs remove std root %ws, Status %x\n", RootShare, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsSetInfo (Obsolete) // // Synopsis: Sets the comment, volume state, or replica state. // // Arguments: [DfsEntryPath] -- Entry Path of the volume for which info is // to be set. // [ServerName] -- If specified, the name of the server whose // state is to be set. // [ShareName] -- If specified, the name of the share on // ServerName whose state is to be set. // [Level] -- Level of DfsInfo // [DfsInfo] -- The actual Dfs info. // // Returns: [NERR_Success] -- Operation completed successfully. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsSetInfo( IN LPWSTR DfsEntryPath, IN LPWSTR ServerName, IN LPWSTR ShareName, IN DWORD Level, IN LPDFS_INFO_STRUCT pDfsInfo) { NET_API_STATUS Status = ERROR_SUCCESS; NET_API_STATUS AccessStatus; DFS_TRACE_HIGH( API, "Net Dfs set info %ws\n", DfsEntryPath); DFS_API_START( ); // // we have to allow resynchronize events from every one. // So do the access check for all calls except the resychronize. // AccessStatus = AccessImpersonateCheckRpcClient(); Status = DfsSetInfoCheckAccess( DfsEntryPath, ServerName, ShareName, Level, (LPBYTE)pDfsInfo, AccessStatus ); DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs set info %ws, Status %x\n", DfsEntryPath, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsSetInfo2 // // Synopsis: Sets the comment, volume state, or replica state. // // Arguments: [DfsEntryPath] -- Entry Path of the volume for which info is // to be set. // [ServerName] -- If specified, the name of the server whose // state is to be set. // [ShareName] -- If specified, the name of the share on // ServerName whose state is to be set. // [Level] -- Level of DfsInfo // [DfsInfo] -- The actual Dfs info. // // Returns: [NERR_Success] -- Operation completed successfully. // // [ERROR_INVALID_LEVEL] -- Level != 100 , 101, or 102 // // [ERROR_INVALID_PARAMETER] -- DfsEntryPath invalid, or // ShareName specified without ServerName. // // [NERR_DfsNoSuchVolume] -- DfsEntryPath does not correspond to // a valid Dfs volume. // // [NERR_DfsNoSuchShare] -- The indicated ServerName/ShareName do // not support this Dfs volume. // // [NERR_DfsInternalCorruption] -- Internal database corruption // encountered while executing operation. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsSetInfo2( IN LPWSTR DfsEntryPath, IN LPWSTR DcName, IN LPWSTR ServerName, IN LPWSTR ShareName, IN DWORD Level, IN LPDFS_INFO_STRUCT pDfsInfo, IN PDFSM_ROOT_LIST *ppRootList) { NET_API_STATUS Status = ERROR_SUCCESS; UNREFERENCED_PARAMETER(ppRootList); UNREFERENCED_PARAMETER(DcName); DFS_TRACE_HIGH( API, "Net Dfs set info2 %ws\n", DfsEntryPath); // // DcName and rootlist not supported, for now. // DFS_API_START( ); Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsSetInfo( DfsEntryPath, ServerName, ShareName, Level, (LPBYTE)pDfsInfo ); } DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs set info %ws, Status %x\n", DfsEntryPath, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsGetInfo // // Synopsis: Server side implementation of the NetDfsGetInfo. // // Arguments: [DfsEntryPath] -- Entry Path of volume for which info is // requested. // // [ServerName] -- Name of server which supports this volume // and for which info is requested. // // [ShareName] -- Name of share on ServerName which supports this // volume. // // [Level] -- Level of Info requested. // // [DfsInfo] -- On successful return, contains a pointer to the // requested DFS_INFO_x struct. // // Returns: [NERR_Success] -- If successfully returned requested info. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsGetInfo( IN LPWSTR DfsEntryPath, IN LPWSTR ServerName, IN LPWSTR ShareName, IN DWORD Level, OUT LPDFS_INFO_STRUCT pDfsInfo) { LONG BufferSize = 0; LONG SizeRequired = 0; ULONG MaxRetry = 0; NET_API_STATUS Status = ERROR_SUCCESS; PDFS_INFO_1 pInfo1 = NULL; UNREFERENCED_PARAMETER(ServerName); UNREFERENCED_PARAMETER(ShareName); DFS_TRACE_HIGH( API, "Net Dfs get info %ws\n", DfsEntryPath); MaxRetry = 5; BufferSize = sizeof(DFS_INFO_STRUCT); DFS_API_START( ); do { pInfo1 = (PDFS_INFO_1)MIDL_user_allocate(BufferSize); if (pInfo1 == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { Status = DfsGetInfo( DfsEntryPath, Level, (LPBYTE)pInfo1, BufferSize, &SizeRequired ); if (Status != ERROR_SUCCESS) { MIDL_user_free( pInfo1 ); } if (Status == ERROR_BUFFER_OVERFLOW) { BufferSize = SizeRequired; } } } while ( (Status == ERROR_BUFFER_OVERFLOW) && (MaxRetry--) ); if (Status == ERROR_SUCCESS) { pDfsInfo->DfsInfo1 = pInfo1; } DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs get info %ws, Status %x\n", DfsEntryPath, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsEnum // // Synopsis: The server side implementation of the NetDfsEnum public API // // Arguments: [Level] -- The level of info struct desired. // [PrefMaxLen] -- Preferred maximum length of output buffer. // 0xffffffff means no limit. // [DfsEnum] -- DFS_INFO_ENUM_STRUCT pointer where the info // structs will be returned. // [ResumeHandle] -- If 0, the enumeration will begin from the // start. On return, the resume handle will be an opaque // cookie that can be passed in on subsequent calls to // resume the enumeration. // // Returns: [NERR_Success] -- Successfully retrieved info. // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsEnum( IN DWORD Level, IN DWORD PrefMaxLen, IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum, IN OUT LPDWORD pResumeHandle) { NET_API_STATUS Status = ERROR_SUCCESS; DFS_TRACE_HIGH( API, "Net Dfs enum %d\n", Level); DFS_API_START(); // // We just call NetRDfsEnumEx with a null pathname. // Status = DfsEnumEx( NULL, Level, PrefMaxLen, pDfsEnum, pResumeHandle ); DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs enum %d, Status %x\n", Level, Status); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsEnumEx // // Synopsis: The DC implementation of the NetDfsEnum public API // // Arguments: [DfsName] -- The Dfs to enumerate (\\domainname\ftdfsname) // [Level] -- The level of info struct desired. // [PrefMaxLen] -- Preferred maximum length of output buffer. // 0xffffffff means no limit. // [DfsEnum] -- DFS_INFO_ENUM_STRUCT pointer where the info // structs will be returned. // [ResumeHandle] -- If 0, the enumeration will begin from the // start. On return, the resume handle will be an opaque // cookie that can be passed in on subsequent calls to // resume the enumeration. // // Returns: [NERR_Success] -- Successfully retrieved info. //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsEnumEx( IN LPWSTR DfsName, IN DWORD Level, IN DWORD PrefMaxLen, IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum, IN OUT LPDWORD pResumeHandle) { NET_API_STATUS Status = ERROR_SUCCESS; DFS_TRACE_HIGH( API, "Net Dfs enum ex %ws\n", DfsName); DFS_API_START (); Status = DfsEnumEx( DfsName, Level, PrefMaxLen, pDfsEnum, pResumeHandle); DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs enum ex %ws, Status %x\n", DfsName, Status); return Status; } NET_API_STATUS DfsEnumEx( IN LPWSTR DfsName, IN DWORD Level, IN DWORD PrefMaxLen, IN OUT LPDFS_INFO_ENUM_STRUCT pDfsEnum, IN OUT LPDWORD pResumeHandle) { DWORD EntriesRead = 0; NET_API_STATUS Status = 0; LPDFS_INFO_1 pInfo1 = NULL; if ((pDfsEnum == NULL) || (pDfsEnum->DfsInfoContainer.DfsInfo1Container == NULL)) { return ERROR_INVALID_PARAMETER; } Status = DfsEnum(DfsName, Level, PrefMaxLen, (LPBYTE *) &pInfo1, &EntriesRead, pResumeHandle); if (Status == ERROR_SUCCESS) { pDfsEnum->DfsInfoContainer.DfsInfo1Container->Buffer = (LPDFS_INFO_1) pInfo1; pDfsEnum->DfsInfoContainer.DfsInfo1Container->EntriesRead = EntriesRead, pDfsEnum->Level = Level; } return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsManagerGetConfigInfo // // Synopsis: RPC Interface method that returns the config info for a // Dfs volume for a given server // // Arguments: [wszServer] -- Name of server requesting the info. This // server is assumed to be requesting the info for // verification of its local volume knowledge. // [wszLocalVolumeEntryPath] -- Entry path of local volume. // [idLocalVolume] -- The guid of the local volume. // [ppRelationInfo] -- The relation info is allocated and // returned here. // // Returns: STATUS_NOT_SUPPORTED // //----------------------------------------------------------------------------- extern "C" DWORD NetrDfsManagerGetConfigInfo( IN LPWSTR wszServer, IN LPWSTR wszLocalVolumeEntryPath, IN GUID idLocalVolume, OUT LPDFSM_RELATION_INFO *ppRelationInfo) { UNREFERENCED_PARAMETER( wszServer); UNREFERENCED_PARAMETER( wszLocalVolumeEntryPath); UNREFERENCED_PARAMETER( idLocalVolume); UNREFERENCED_PARAMETER( ppRelationInfo); // // This will probably be never supported. // return ERROR_NOT_SUPPORTED; } //+---------------------------------------------------------------------------- // // Function: NetrDfsManagerSendSiteInfo // // Synopsis: RPC Interface method that reports the site information for a // Dfs storage server. // // Arguments: [wszServer] -- Name of server sending the info. // [pSiteInfo] -- The site info is here. // // Returns: STATUS_NOT_SUPPORTED // //----------------------------------------------------------------------------- extern "C" DWORD NetrDfsManagerSendSiteInfo( IN LPWSTR wszServer, IN LPDFS_SITELIST_INFO pSiteInfo) { UNREFERENCED_PARAMETER( wszServer); UNREFERENCED_PARAMETER( pSiteInfo); // // This will probably be never supported. // return ERROR_NOT_SUPPORTED; } //+---------------------------------------------------------------------------- // // Function: NetrDfsManagerInitialize // // Synopsis: Reinitializes the service // // Arguments: [ServerName] -- Name of server // [Flags] -- Flags for the operation // // Returns: STATUS_NOT_SUPPORTED // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsManagerInitialize( IN LPWSTR ServerName, IN DWORD Flags) { UNREFERENCED_PARAMETER( ServerName); UNREFERENCED_PARAMETER( Flags); // // This will probably be never supported. // return ERROR_NOT_SUPPORTED; } //+---------------------------------------------------------------------------- // // Function: NetrDfsMove // // Synopsis: Moves a leaf volume to a different parent. // // Arguments: [DfsEntryPath] -- Current entry path of Dfs volume. // // [NewEntryPath] -- New entry path of Dfs volume. // // Returns: STATUS_NOT_SUPPORTED // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsMove( IN LPWSTR DfsEntryPath, IN LPWSTR NewDfsEntryPath) { UNREFERENCED_PARAMETER( DfsEntryPath); UNREFERENCED_PARAMETER( NewDfsEntryPath); // // This will definitely be never supported. // return ERROR_NOT_SUPPORTED; } //+---------------------------------------------------------------------------- // // Function: NetrDfsRename // // Synopsis: Moves a leaf volume to a different parent. // // Arguments: [Path] -- Current path along the entry path of a Dfs volume. // // [NewPath] -- New path for current path. // // Returns: STATUS_NOT_SUPPORTED // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsRename( IN LPWSTR Path, IN LPWSTR NewPath) { UNREFERENCED_PARAMETER( Path); UNREFERENCED_PARAMETER( NewPath); // // This will definitely be never supported. // return ERROR_NOT_SUPPORTED; } // ==================================================================== // MIDL allocate and free // // These routines are used by the RPC layer to call back into our // code to allocate or free memory. // // ==================================================================== PVOID MIDL_user_allocate(size_t len) { return malloc(len); } VOID MIDL_user_free(void * ptr) { free(ptr); } //+------------------------------------------------------------------------- // // Function: RpcInit - Initialize the RPC for this server. // // Arguments: NONE // // Returns: Status // ERROR_SUCCESS if we initialized without errors // // Description: This routine sets up the RPC server to listen to the // api requests originating from the clients. // //-------------------------------------------------------------------------- DWORD DfsApiInit() { RPC_STATUS Status = 0; LPWSTR ProtocolSequence = L"ncacn_np"; PVOID Security = NULL; /* let the security subsystem assign appropriate SD */ LPWSTR Endpoint = L"\\pipe\\netdfs"; unsigned int cMinCalls = 1; unsigned int cMaxCalls = RPC_C_LISTEN_MAX_CALLS_DEFAULT; unsigned int fDontWait = TRUE; DfsLockInitialized = InitializeCriticalSectionAndSpinCount( &DfsApiLock, 0 ); if(DfsLockInitialized == FALSE) { Status = GetLastError(); return Status; } // // We register our protocol, and startup a server to listen to RPC // requests. A new server thread is started, so that our thread // can return back to the caller. // Status = RpcServerUseProtseqEpW((USHORT *)ProtocolSequence, cMaxCalls, (USHORT *)Endpoint, Security); if (Status == ERROR_SUCCESS) { Status = RpcServerRegisterIf(netdfs_ServerIfHandle, NULL, NULL); if (Status == ERROR_SUCCESS) { Status = RpcServerListen(cMinCalls, cMaxCalls, fDontWait); if (Status == RPC_S_OK ) { ServerListen = TRUE; } } } return Status; } void DfsApiShutDown(void) { RPC_STATUS Status = RPC_S_OK; // // stop server listen. // if(ServerListen) { Status = RpcMgmtStopServerListening(0); // // wait for all RPC threads to go away. // if( Status == RPC_S_OK) { Status = RpcMgmtWaitServerListen(); } ServerListen = FALSE; } Status = RpcServerUnregisterIf(netdfs_ServerIfHandle, NULL, TRUE); // wait for calls to complete if(DfsLockInitialized) { DeleteCriticalSection(&DfsApiLock); } } //+---------------------------------------------------------------------------- // // Function: NetrDfsAddFtRoot // // Synopsis: Creates a new FtDfs, or joins a Server into an FtDfs // // Arguments: [ServerName] -- Name of server backing the volume. // [DcName] -- DC to use // [RootShare] -- Name of share on ServerName backing the volume. // [FtDfsName] -- The Name of the FtDfs to create/join // [Comment] -- Comment associated with this root. // [Flags] -- Flags for the operation // [ppRootList] -- On success, returns a list of roots that need to be // informed of the change in the DS object // // Returns: [NERR_Success] -- Operation succeeded. // // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsAddFtRoot( IN LPWSTR ServerName, IN LPWSTR DcName, IN LPWSTR RootShare, IN LPWSTR FtDfsName, IN LPWSTR Comment, IN LPWSTR ConfigDN, IN BOOLEAN NewFtDfs, IN DWORD ApiFlags, IN PDFSM_ROOT_LIST *ppRootList) { NET_API_STATUS Status = ERROR_SUCCESS; UNREFERENCED_PARAMETER( ConfigDN); if ( (DcName == NULL) || (DcName[0] == UNICODE_NULL) || (RootShare == NULL) || (RootShare[0] == UNICODE_NULL) || (FtDfsName == NULL) || (FtDfsName[0] == UNICODE_NULL) || (ServerName == NULL) || (ServerName[0] == UNICODE_NULL) ) { return ERROR_INVALID_PARAMETER; } DFS_TRACE_HIGH( API, "Net Dfs Add FT Root %ws\n", RootShare); DFS_API_START( ); Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsAddADBlobRoot( ServerName, DcName, RootShare, FtDfsName, Comment, NewFtDfs, ApiFlags, (PVOID)ppRootList ); } DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Add AD blob Root %ws\n", RootShare); return Status; } //+---------------------------------------------------------------------------- // // Function: NetrDfsRemoveFtRoot // // Synopsis: Deletes a root from an FtDfs. // // Arguments: [ServerName] -- The server to remove. // [DcName] -- DC to use // [RootShare] -- The Root share hosting the Dfs/FtDfs // [FtDfsName] -- The FtDfs to remove the root from. // [Flags] -- Flags for the operation // [ppRootList] -- On success, returns a list of roots that need to be // informed of the change in the DS object // // Returns: [NERR_Success] -- Operation successful. // // //----------------------------------------------------------------------------- extern "C" NET_API_STATUS NetrDfsRemoveFtRoot( IN LPWSTR ServerName, IN LPWSTR DcName, IN LPWSTR RootShare, IN LPWSTR FtDfsName, IN DWORD ApiFlags, IN PDFSM_ROOT_LIST *ppRootList) { NET_API_STATUS Status = ERROR_SUCCESS; if ( (DcName == NULL) || (DcName[0] == UNICODE_NULL) || (RootShare == NULL) || (RootShare[0] == UNICODE_NULL) || (FtDfsName == NULL) || (FtDfsName[0] == UNICODE_NULL) || (ServerName == NULL) || (ServerName[0] == UNICODE_NULL) ) { return ERROR_INVALID_PARAMETER; } DFS_TRACE_HIGH( API, "Net Dfs Remove FT Root %ws\n", RootShare); DFS_API_START( ); Status = AccessImpersonateCheckRpcClient(); if (Status == ERROR_SUCCESS) { Status = DfsDeleteADBlobRoot( ServerName, DcName, RootShare, FtDfsName, ApiFlags, (PVOID)ppRootList ); } DFS_API_END( ); DFS_TRACE_ERROR_HIGH( Status, API, "Net Dfs Remove AD blob Root %ws\n", RootShare); return Status; }