windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/srvsvc/client/srvstub.c
2020-09-26 16:20:57 +08:00

3689 lines
91 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991-1992 Microsoft Corporation
Module Name:
SrvStub.C
Abstract:
These are the server service API RPC client stubs.
Author:
Dan Lafferty (danl) 06-Feb-1991
Environment:
User Mode - Win32
Revision History:
06-Feb-1991 Danl
Created
07-Jun-1991 JohnRo
Added downlevel support for NetServer APIs.
Added NET_API_FUNCTION where necessary.
15-Jul-1991 RFirth
Integrated RxNetShare routines into NetShare stubs
24-Jul-1991 JohnRo
Implement downlevel NetConnectionEnum. Try using <netrpc.h> macros.
25-Jul-1991 JohnRo
Quiet DLL stub debug output. Use NetRpc.h macros for NetServer APIs.
06-Sep-1991 JohnRo
Downlevel NetFile APIs.
25-Sep-1991 JohnRo
Use NetRpc.h macros for all other APIs, to quiet normal debug output.
07-Oct-1991 JohnRo
RAID 3210: "NET FILE 0" causes assertion. (Was bug in NetFileGetInfo
DLL stub.)
16-Oct-1991 JohnRo
Implement remote NetSession APIs. Changed LPSTR to LPTSTR.
07-Nov-1991 JohnRo
RAID 4186: assert in RxNetShareAdd and other DLL stub problems.
12-Nov-1991 JohnRo
APIs in this file need SERVICE_SERVER started to run locally.
04-Dec-1991 JohnRo
Change RxNetServerSetInfo() to new-style interface.
Fixed bug in calling RxNetShareSetInfo().
09-May-1992 rfirth
Resurrect NetStatisticsGet as NetServerStatisticsGet
5-Aug-1992 JohnsonA
Added new share info level 502 to enable passing of security
descriptors.
08-Sep-1992 JohnRo
Fix NET_API_FUNCTION references.
--*/
//
// INCLUDES
//
#include <nt.h> // DbgPrint prototype
#include <ntrtl.h> // DbgPrint
#include <rpc.h> // DataTypes and runtime APIs
#include <srvsvc.h> // generated by the MIDL complier
#include <rpcutil.h> // GENERIC_ENUM_STRUCT
#include <lmcons.h> // NET_API_STATUS
#include <debuglib.h> // (needed by netrpc.h)
#include <lmsvc.h> // (needed by netrpc.h)
#include <netdebug.h> // (needed by netrpc.h)
#include <lmerr.h> // NetError codes
#include <netlib.h> // NetpIsServiceStarted().
#include <netlibnt.h> // NetpNtStatusToApiStatus
#include <netrpc.h> // NET_REMOTE_ macros.
#include <lmremutl.h> // SUPPORTS_RPC
#include <lmshare.h> // Required by rxsess.h.
#include <rap.h> // Needed by <rxserver.h>.
#include <rxconn.h> // RxNetConnection routines.
#include <rxfile.h> // RxNetFile routines.
#include <rxremutl.h> // RxNetRemoteTOD
#include <rxserver.h> // RxNetServer routines.
#include <rxsess.h> // RxNetSession routines.
#include <rxshare.h> // RxNetShare routines
#include <icanon.h> // NetpIsRemote
#include <netstats.h> // NetServerStatisticsGet private prototype
#include <rxstats.h> // RxNetStatisticsGet (down-level)
#include <netcan.h> // prototypes for Netps canonicalization functions
#include <rxcanon.h> // prototypes for down-level canonicalization functions
#include <tstr.h>
#include "cscp.h"
#define SET_ERROR_PARAMETER(a) \
if ( ARGUMENT_PRESENT( parm_err ) ) { *parm_err = a; }
NET_API_STATUS NET_API_FUNCTION
NetCharDevControl (
IN LPCWSTR servername,
IN LPCWSTR devname,
IN DWORD opcode
)
/*++
Routine Description:
This is the DLL entrypoint for NetCharDevControl.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
devname --A pointer to the ASCIIZ string containing the name of
the device to control
opcode --Control opcode: currently defined are:
CHARDEV_CLOSE for the device closed.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrCharDevControl (
(LPWSTR)servername,
(LPWSTR)devname,
opcode);
NET_REMOTE_RPC_FAILED(
"NetCharDevControl",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetCharDevControl
NET_API_STATUS NET_API_FUNCTION
NetCharDevEnum (
IN LPCWSTR servername,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetCharDevEnum.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
level --Level of information required. 0 and 1 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
prefmaxlen --Prefered maximum length of returned data (in 8-bit
bytes). 0xffffffff specifies no limit.
entriesread --On return the actual enumerated element count is
located in the DWORD pointed to by entriesread.
totalentries --On return the total entries available to be
enumerated is located in the DWORD pointed to by
totalentries.
resumehandle --On return, a resume handle is stored in the DWORD
pointed to by resumehandle, and is used to continue an
existing character device search. The handle should be zero
on the first call and left unchanged for subsequent calls. If
resumehandle is NULL, then no resume handle is stored..
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
apiStatus = NetrCharDevEnum (
(LPWSTR)servername,
(LPCHARDEV_ENUM_STRUCT)&infoStruct,
prefmaxlen,
totalentries,
resume_handle);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
*entriesread = genericInfoContainer.EntriesRead;
} else {
*bufptr = NULL;
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED(
"NetCharDevEnum",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetCharDevEnum
NET_API_STATUS NET_API_FUNCTION
NetCharDevGetInfo (
IN LPCWSTR servername,
IN LPCWSTR devname,
IN DWORD level,
OUT LPBYTE *bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetCharDevGetInfo.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
devname --A pointer to the ASCIIZ string containing the name of
the device to return information on.
level --Level of information required. 0 and 1 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
*bufptr = NULL; // Must be NULL so RPC knows to till it in.
NET_REMOTE_TRY_RPC
apiStatus = NetrCharDevGetInfo (
(LPWSTR)servername,
(LPWSTR)devname,
level,
(LPCHARDEV_INFO) bufptr);
NET_REMOTE_RPC_FAILED(
"NetCharDevGetInfo",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetCharDevGetInfo
NET_API_STATUS NET_API_FUNCTION
NetCharDevQEnum (
IN LPCWSTR servername,
IN LPCWSTR username,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetCharDevQEnum.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
username --A pointer to an ASCIIZ string containing an a username
for the active queues of interest. This parameter is
optional, if NULL then all device queues are enumerated.
level --Level of information required. 0 and 1 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
prefmaxlen --Prefered maximum length of returned data (in 8-bit
bytes). 0xffffffff specifies no limit.
entriesread --On return the actual enumerated element count is
located in the DWORD pointed to by entriesread.
totalentries --On return the total entries available to be
enumerated is located in the DWORD pointed to by
totalentries.
resumehandle --On return, a resume handle is stored in the DWORD
pointed to by resumehandle, and is used to continue an
existing character device queue search. The handle should be
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
apiStatus = NetrCharDevQEnum (
(LPWSTR)servername,
(LPWSTR)username,
(LPCHARDEVQ_ENUM_STRUCT) &infoStruct,
prefmaxlen,
totalentries,
resume_handle);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
*entriesread = genericInfoContainer.EntriesRead;
} else {
*bufptr = NULL;
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED(
"NetCharDevQEnum",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetCharDevQEnum
NET_API_STATUS NET_API_FUNCTION
NetCharDevQGetInfo (
IN LPCWSTR servername,
IN LPCWSTR queuename,
IN LPCWSTR username,
IN DWORD level,
OUT LPBYTE *bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetCharDevQGetInfo.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
queuename --A pointer to an ASCIIZ string containing the name of
the queue to return information on.
username --A pointer to an ASCIIZ string containing the username
of the a user whose job of of interest for the cq1_numahead
count.
level --Level of information required. 0 and 1 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
*bufptr = NULL; // Must be NULL so RPC knows to till it in.
NET_REMOTE_TRY_RPC
apiStatus = NetrCharDevQGetInfo (
(LPWSTR)servername,
(LPWSTR)queuename,
(LPWSTR)username,
level,
(LPCHARDEVQ_INFO) bufptr);
NET_REMOTE_RPC_FAILED(
"NetCharDevQGetInfo",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetCharDevQGetInfo
NET_API_STATUS NET_API_FUNCTION
NetCharDevQPurge (
IN LPCWSTR servername,
IN LPCWSTR queuename
)
/*++
Routine Description:
This is the DLL entrypoint for NetCharDevQPurge.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
queuename --A pointer to an ASCIIZ string containing the name of
the queue to be purged.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrCharDevQPurge (
(LPWSTR)servername,
(LPWSTR)queuename);
NET_REMOTE_RPC_FAILED(
"NetCharDevQPurge",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetCharDevQPurge
NET_API_STATUS NET_API_FUNCTION
NetCharDevQPurgeSelf (
IN LPCWSTR servername,
IN LPCWSTR queuename,
IN LPCWSTR computername
)
/*++
Routine Description:
This is the DLL entrypoint for NetCharDevQPurgeSelf.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
queuename --A pointer to an ASCIIZ string containing the name of
the queue to be purged of pending entries from the specified
computer.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrCharDevQPurgeSelf (
(LPWSTR)servername,
(LPWSTR)queuename,
(LPWSTR)computername);
NET_REMOTE_RPC_FAILED(
"NetCharDevQPurgeSelf",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetCharDevQPurgeSelf
NET_API_STATUS NET_API_FUNCTION
NetCharDevQSetInfo (
IN LPCWSTR servername,
IN LPCWSTR queuename,
IN DWORD level,
IN LPBYTE buf,
OUT LPDWORD parm_err
)
/*++
Routine Description:
This is the DLL entrypoint for NetCharDevQSetInfo.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
queuename --A pointer to an ASCIIZ string containing the name of
the queue to set information on.
level --Level of information to set.
buf --A pointer to a buffer containing the chardev information.
If parmnum is non zero then the buffer contains only the
appropriate data for the specific element. If parmnum is
zero, then the buffer contains the whole chardev information
structure.
parm_err --Optional pointer to a DWORD to return the index of the
first parameter in error when ERROR_INVALID_PARAMETER is
returned. If NULL the parameter is not returned on error.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrCharDevQSetInfo (
(LPWSTR)servername,
(LPWSTR)queuename,
level,
(LPCHARDEVQ_INFO) &buf,
parm_err);
NET_REMOTE_RPC_FAILED(
"NetCharDevQSetInfo",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetCharDevQSetInfo
NET_API_STATUS NET_API_FUNCTION
NetConnectionEnum (
IN LPTSTR servername,
IN LPTSTR qualifier,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetConnectionEnum.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
qualifier --A pointer to an ASCIIZ string containing a sharename
or computername for the connections of interest. If it is a
sharename, then all the connections made to that sharename
are listed. If it is a computername (i.e. it starts with two
backslash characters), then NetConnectionEnum lists all
connections made from that computer to the server specified.
level --Level of information required. 0 and 1 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
prefmaxlen --Prefered maximum length of returned data (in 8-bit
bytes). 0xffffffff specifies no limit.
entriesread --On return the actual enumerated element count is
located in the DWORD pointed to by entriesread.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
apiStatus = NetrConnectionEnum (
servername,
qualifier,
(LPCONNECT_ENUM_STRUCT)&infoStruct,
prefmaxlen,
totalentries,
resume_handle);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
*entriesread = genericInfoContainer.EntriesRead;
} else {
*bufptr = NULL;
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED(
"NetConnectionEnum",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Try call to downlevel.
//
apiStatus = RxNetConnectionEnum(
servername,
qualifier,
level,
bufptr,
prefmaxlen,
entriesread,
totalentries,
resume_handle
);
NET_REMOTE_END
return(apiStatus);
} // NetConnectionEnum
NET_API_STATUS NET_API_FUNCTION
NetFileClose (
IN LPTSTR servername,
IN DWORD fileid
)
/*++
Routine Description:
This is the DLL entrypoint for NetFileClose.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
fileid --The fileid of the opened resource instance to be closed.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrFileClose (
servername,
fileid);
NET_REMOTE_RPC_FAILED(
"NetFileClose",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = RxNetFileClose (
servername,
fileid);
NET_REMOTE_END
return(apiStatus);
}
NET_API_STATUS NET_API_FUNCTION
NetFileEnum (
IN LPTSTR servername,
IN LPTSTR basepath,
IN LPTSTR username,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT PDWORD_PTR resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetFileEnum.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
basepath --A pointer to an ASCIIZ string containing a qualifier
for the returned information. If NULL then all open resources
are enumerated, else only resources which have basepath as a
prefix are enumerated.
username --A pointer to an ASCIIZ string that specifies the name
of the user. If not NULL, username serves as a qualifier to
the ennumeration. The files returned are limited to those
that have usernames matching the qualifier. If username is
NULL, no username qualifier is used.
level --Level of information required. 2 and 3 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
prefmaxlen --Prefered maximum length of returned data (in 8-bit
bytes). 0xffffffff specifies no limit.
entriesread --On return the actual enumerated element count is
located in the DWORD pointed to by entriesread.
totalentries --On return the total entries available to be
enumerated is located in the DWORD pointed to by
totalentries.
resumehandle --On return, a resume handle is stored in the DWORD
pointed to by resumehandle, and is used to continue an
existing file search. The handle should be zero on the first
call and left unchanged for subsequent calls. If resumehandle
is NULL, then no resume handle is stored..
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
//
// NetrFileEnum's resume_handle parm is a true index that will remain
// 32 bits wide for on-the-wire compatibility. Thus, the cast to
// (PDWORD) here works.
//
apiStatus = NetrFileEnum (
servername,
basepath,
username,
(LPFILE_ENUM_STRUCT) &infoStruct,
prefmaxlen,
totalentries,
(PDWORD)resume_handle);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
*entriesread = genericInfoContainer.EntriesRead;
} else {
*bufptr = NULL;
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED(
"NetFileEnum",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = RxNetFileEnum(
servername,
basepath,
username,
level,
bufptr,
prefmaxlen,
entriesread,
totalentries,
resume_handle);
NET_REMOTE_END
return(apiStatus);
} // NetFileEnum
NET_API_STATUS NET_API_FUNCTION
NetFileGetInfo (
IN LPTSTR servername,
IN DWORD fileid,
IN DWORD level,
OUT LPBYTE *bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetFileGetInfo.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
fileid --The fileid of the open resource to return information
on. The fileid value must be that returned in a previous
enumeration call.
level --Level of information required. 2 and 3 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
*bufptr = NULL; // Must be NULL so RPC knows to fill it in.
NET_REMOTE_TRY_RPC
apiStatus = NetrFileGetInfo (
servername,
fileid,
level,
(LPFILE_INFO) bufptr);
NET_REMOTE_RPC_FAILED(
"NetFileGetInfo",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
apiStatus = RxNetFileGetInfo (
servername,
fileid,
level,
bufptr);
NET_REMOTE_END
return(apiStatus);
} // NetFileGetInfo
NET_API_STATUS NET_API_FUNCTION
NetSessionDel (
IN LPTSTR servername,
IN LPTSTR clientname,
IN LPTSTR username
)
/*++
Routine Description:
This is the DLL entrypoint for NetSessionDel.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
clientname --A pointer to an ASCIIZ string containing the
computername of the client to disconnect.
username --A pointer to an ASCIIZ string containing the name of
the user whose session is to be terminated. A NULL indicates
that all users' sessions from the computername specified are
to be terminated.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrSessionDel (
servername,
clientname,
username);
NET_REMOTE_RPC_FAILED("NetSessionDel", servername, apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER )
//
// Call downlevel version of the API.
//
apiStatus = RxNetSessionDel (
servername,
clientname,
username);
NET_REMOTE_END
return(apiStatus);
} // NetSessionDel
NET_API_STATUS NET_API_FUNCTION
NetSessionEnum (
IN LPTSTR servername,
IN LPTSTR clientname,
IN LPTSTR username,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetSessionEnum.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
clientname --A pointer to an ASCIIZ string containing the name of
the computer session for which information is to be returned.
A NULL pointer or string specifies that all computer sessions
on the server are to be ennumerated.
username --A pointer to an ASCIIZ string containing the name of
the the user for which to ennumerate the sessions. A NULL
pointer or string specifies that sessions for all users are
to be ennumerated.
level --Level of information required. 0, 1, 2 and 10 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
prefmaxlen --Prefered maximum length of returned data (in 8-bit
bytes). 0xffffffff specifies no limit.
entriesread --On return the actual enumerated element count is
located in the DWORD pointed to by entriesread.
totalentries --On return the total entries available to be
enumerated is located in the DWORD pointed to by
totalentries.
resumehandle --On return, a resume handle is stored in the DWORD
pointed to by resumehandle, and is used to continue an
existing session search. The handle should be zero on the
first call and left unchanged for subsequent calls. If
resumehandle is NULL, then no resume handle is stored.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
apiStatus = NetrSessionEnum (
servername,
clientname,
username,
(PSESSION_ENUM_STRUCT) &infoStruct,
prefmaxlen,
totalentries,
resume_handle);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
*entriesread = genericInfoContainer.EntriesRead;
} else {
*bufptr = NULL;
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED("NetSessionEnum", servername, apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER )
//
// Call downlevel version of the API.
//
apiStatus = RxNetSessionEnum (
servername,
clientname,
username,
level,
bufptr,
prefmaxlen,
entriesread,
totalentries,
resume_handle);
NET_REMOTE_END
return(apiStatus);
} // NetSessionEnum
NET_API_STATUS NET_API_FUNCTION
NetSessionGetInfo (
IN LPTSTR servername,
IN LPTSTR clientname,
IN LPTSTR username,
IN DWORD level,
OUT LPBYTE *bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetSessionEnum.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
clientname --A pointer to an ASCIIZ string containing the name of
the computer session for which information is to be returned.
This field cannot be NULL.
username --A pointer to an ASCIIZ string containing the name of
the the user for which to ennumerate the sessions. This field
cannot be NULL.
level --Level of information required. 0, 1, 2 and 10 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
DWORD totalentries;
if ( clientname == NULL || username == NULL ) {
return ERROR_INVALID_PARAMETER;
}
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
apiStatus = NetrSessionEnum (
servername,
clientname,
username,
(PSESSION_ENUM_STRUCT) &infoStruct,
(DWORD)-1,
&totalentries,
NULL);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
} else {
*bufptr = NULL;
if ( apiStatus == NO_ERROR ) {
return NERR_ClientNameNotFound;
}
}
NET_REMOTE_RPC_FAILED("NetSessionGetInfo", servername, apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER )
//
// Call downlevel version of the API.
//
apiStatus = RxNetSessionGetInfo (
servername,
clientname,
username,
level,
bufptr);
NET_REMOTE_END
return(apiStatus);
} // NetSessionGetInfo
NET_API_STATUS NET_API_FUNCTION
NetShareAdd (
IN LPTSTR servername,
IN DWORD level,
IN LPBYTE buf,
OUT LPDWORD parm_err
)
/*++
Routine Description:
This is the DLL entrypoint for NetShareAdd. Only levels 2 and 502
are allowed.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
level --Level of information provided. Must be 2.
buf --A pointer to a buffer containing the share information
structure.
parm_err --Optional pointer to a DWORD to return the index of the
first parameter in error when ERROR_INVALID_PARAMETER is
returned. If NULL the parameter is not returned on error.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NTSTATUS status;
ULONG SDLength = 0;
ULONG oldSDLength;
PSECURITY_DESCRIPTOR securityDescriptor = NULL;
PSECURITY_DESCRIPTOR oldSecurityDescriptor = NULL;
//
// do the parameter validation here - this way we only need do it once and
// in a centralized place
//
if (level != 2 && level != 502) {
return ERROR_INVALID_LEVEL;
}
NET_REMOTE_TRY_RPC
if ( level == 502 ) {
PSHARE_INFO_502 shi502 = (LPSHARE_INFO_502) buf;
//
// Save this. We need to restore this later.
//
oldSecurityDescriptor = shi502->shi502_security_descriptor;
oldSDLength = shi502->shi502_reserved;
if ( oldSecurityDescriptor != NULL ) {
if ( !RtlValidSecurityDescriptor( oldSecurityDescriptor) ) {
SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
return ERROR_INVALID_PARAMETER;
}
//
// Make a self relative security descriptor for use in the
// RPC call..
//
status = RtlMakeSelfRelativeSD(
oldSecurityDescriptor,
NULL,
&SDLength
);
if (status != STATUS_BUFFER_TOO_SMALL) {
SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
return(ERROR_INVALID_PARAMETER);
} else {
securityDescriptor = MIDL_user_allocate( SDLength );
if ( securityDescriptor == NULL) {
return ERROR_NOT_ENOUGH_MEMORY;
} else {
//
// make an appropriate self-relative security descriptor
//
status = RtlMakeSelfRelativeSD(
oldSecurityDescriptor,
(PSECURITY_DESCRIPTOR) securityDescriptor,
&SDLength
);
if ( !NT_SUCCESS(status) ) {
MIDL_user_free( securityDescriptor );
SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
return(ERROR_INVALID_PARAMETER);
}
shi502->shi502_security_descriptor = securityDescriptor;
shi502->shi502_reserved = SDLength;
}
}
} else {
shi502->shi502_reserved = 0;
}
}
apiStatus = NetrShareAdd (
servername,
level,
(LPSHARE_INFO) &buf,
parm_err);
if ( securityDescriptor != NULL ) {
//
// restore old values
//
PSHARE_INFO_502 shi502 = (LPSHARE_INFO_502) buf;
shi502->shi502_security_descriptor = oldSecurityDescriptor;
shi502->shi502_reserved = oldSDLength;
MIDL_user_free( securityDescriptor );
}
NET_REMOTE_RPC_FAILED(
"NetShareAdd",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Call downlevel server.
//
if ( level != 502 ) {
apiStatus = RxNetShareAdd(
servername,
2,
buf,
parm_err
);
} else {
apiStatus = ERROR_NOT_SUPPORTED;
}
NET_REMOTE_END
return(apiStatus);
} // NetShareAdd
NET_API_STATUS NET_API_FUNCTION
NetShareCheck (
IN LPTSTR servername,
IN LPTSTR device,
OUT LPDWORD type
)
/*++
Routine Description:
This is the DLL entrypoint for NetShareCheck
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
device --A pointer to an ASCIIZ string containing the name of the
device to check for shared access.
type --On return the address pointed to by the type parameter
contains the type of share the device is offered with. This
field is only set if success was returned.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
if (!(device && *device) || !type) {
return ERROR_INVALID_PARAMETER;
}
NET_REMOTE_TRY_RPC
apiStatus = NetrShareCheck (
servername,
device,
type);
NET_REMOTE_RPC_FAILED(
"NetShareCheck",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Call downlevel server.
//
apiStatus = RxNetShareCheck(servername, device, type);
NET_REMOTE_END
return(apiStatus);
} // NetShareCheck
NET_API_STATUS NET_API_FUNCTION
NetShareDel (
IN LPTSTR servername,
IN LPTSTR netname,
IN DWORD reserved
)
/*++
Routine Description:
This is the DLL entrypoint for NetShareDel.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
netname --A pointer to an ASCIIZ string containing the netname of
the share to delete.
reserved --Reserved, must be zero.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
BOOL committingIpcDelete = FALSE;
SHARE_DEL_HANDLE handle;
BOOL tryDownLevel = FALSE;
if ( !netname || (*netname == 0) || reserved ) {
return ERROR_INVALID_PARAMETER;
}
RpcTryExcept {
if ( STRICMP( netname, TEXT("IPC$") ) != 0 ) {
apiStatus = NetrShareDel(
servername,
netname,
reserved
);
} else {
apiStatus = NetrShareDelStart(
servername,
netname,
reserved,
&handle
);
if ( apiStatus == NERR_Success ) {
committingIpcDelete = TRUE;
apiStatus = NetrShareDelCommit( &handle );
}
}
} RpcExcept ( 1 ) {
RPC_STATUS rpcStatus;
rpcStatus = RpcExceptionCode( );
if ( committingIpcDelete && (rpcStatus == RPC_S_CALL_FAILED) ) {
apiStatus = NERR_Success;
} else {
apiStatus = NetpHandleRpcFailure(
"NetShareDel",
rpcStatus,
servername,
SERVICE_SERVER,
NET_REMOTE_FLAG_NORMAL,
&tryDownLevel
);
}
}
RpcEndExcept
if (apiStatus == NERR_TryDownLevel) {
tryDownLevel = TRUE;
}
if ( tryDownLevel ) {
//
// Call downlevel server.
//
// note: push value 0 instead of real reserved
//
apiStatus = RxNetShareDel(servername, netname, 0);
}
return apiStatus;
} // NetShareDel
NET_API_STATUS NET_API_FUNCTION
NetShareDelSticky (
IN LPTSTR servername,
IN LPTSTR netname,
IN DWORD reserved
)
/*++
Routine Description:
This is the DLL entrypoint for NetShareDelSticky.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
netname --A pointer to an ASCIIZ string containing the netname of
the share to delete.
reserved --Reserved, must be zero.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
if (!(netname && *netname) || reserved) {
return ERROR_INVALID_PARAMETER;
}
NET_REMOTE_TRY_RPC
apiStatus = NetrShareDelSticky (
servername,
netname,
reserved);
NET_REMOTE_RPC_FAILED(
"NetShareDelSticky",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// No downlevel call.
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetShareDelSticky
NET_API_STATUS NET_API_FUNCTION
NetShareEnum (
IN LPTSTR servername,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetShareEnum
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
level --Level of information required. 0, 1 and 2 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
prefmaxlen --Prefered maximum length of returned data (in 8-bit
bytes). 0xffffffff specifies no limit.
entriesread --On return the actual enumerated element count is
located in the DWORD pointed to by entriesread.
totalentries --On return the total entries available to be
enumerated is located in the DWORD pointed to by
totalentries.
resumehandle --On return, a resume handle is stored in the DWORD
pointed to by resumehandle, and is used to continue an
existing share search. The handle should be zero on the first
call and left unchanged for subsequent calls. If resumehandle
is NULL, then no resume handle is stored..
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
//
// check the caller's parameters
//
*totalentries = *entriesread = 0;
*bufptr = NULL;
if ( (level > 2) && (level != 501) && (level != 502) ) {
return ERROR_INVALID_LEVEL;
}
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
apiStatus = NetrShareEnum (
servername,
(LPSHARE_ENUM_STRUCT) &infoStruct,
prefmaxlen,
totalentries,
resume_handle);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
*entriesread = genericInfoContainer.EntriesRead;
} else {
*bufptr = NULL;
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED(
"NetShareEnum",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Call downlevel server.
//
if ( level != 502 && level != 501 ) {
apiStatus = RxNetShareEnum(servername, level, bufptr,
prefmaxlen, entriesread, totalentries, resume_handle);
} else {
apiStatus = ERROR_NOT_SUPPORTED;
}
NET_REMOTE_END
//
// If we haven't gotten anything, and the server is offline,
// return the offline share state
//
if( ( *bufptr == NULL || *entriesread == 0 ) &&
ARGUMENT_PRESENT( servername ) &&
CSCIsServerOffline( servername ) ) {
NET_API_STATUS cscStatus;
cscStatus = CSCNetShareEnum(
servername,
level,
bufptr,
entriesread,
totalentries
);
if( cscStatus == NERR_Success ) {
apiStatus = cscStatus;
}
}
return(apiStatus);
} // NetShareEnum
NET_API_STATUS NET_API_FUNCTION
NetShareEnumSticky (
IN LPTSTR servername,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetShareEnumSticky
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
level --Level of information required. 0, 1 and 2 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
prefmaxlen --Prefered maximum length of returned data (in 8-bit
bytes). 0xffffffff specifies no limit.
entriesread --On return the actual enumerated element count is
located in the DWORD pointed to by entriesread.
totalentries --On return the total entries available to be
enumerated is located in the DWORD pointed to by
totalentries.
resumehandle --On return, a resume handle is stored in the DWORD
pointed to by resumehandle, and is used to continue an
existing share search. The handle should be zero on the first
call and left unchanged for subsequent calls. If resumehandle
is NULL, then no resume handle is stored..
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
//
// check the caller's parameters
//
*totalentries = *entriesread = 0;
*bufptr = NULL;
if ( (level > 2) && (level != 501) && (level != 502) ) {
return ERROR_INVALID_LEVEL;
}
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
apiStatus = NetrShareEnumSticky (
servername,
(LPSHARE_ENUM_STRUCT) &infoStruct,
prefmaxlen,
totalentries,
resume_handle);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
*entriesread = genericInfoContainer.EntriesRead;
} else {
*bufptr = NULL;
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED(
"NetShareEnum",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// No downlevel support
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetShareEnumSticky
NET_API_STATUS NET_API_FUNCTION
NetShareGetInfo (
IN LPTSTR servername,
IN LPTSTR netname,
IN DWORD level,
OUT LPBYTE *bufptr
)
/*++
Routine Description:
NetShareGetInfo
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
netname --A pointer to an ASCIIZ string containing the netname of
the share to return information on.
level --Level of information required. 0, 1 and 2 are valid.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
if (bufptr == NULL) {
return ERROR_INVALID_PARAMETER;
}
*bufptr = NULL; // Must be NULL so RPC knows to fill it in.
if ( (level > 2) &&
(level != 501) &&
(level != 502) &&
(level != 1005) ) {
return ERROR_INVALID_LEVEL;
}
if (!(netname && *netname)) {
return ERROR_INVALID_PARAMETER;
}
NET_REMOTE_TRY_RPC
apiStatus = NetrShareGetInfo (
servername,
netname,
level,
(LPSHARE_INFO) bufptr);
NET_REMOTE_RPC_FAILED(
"NetShareGetInfo",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Call downlevel server.
//
if( level == 0 || level == 1 || level == 2 ) {
apiStatus = RxNetShareGetInfo(servername, netname, level, bufptr);
} else {
apiStatus = ERROR_NOT_SUPPORTED;
}
NET_REMOTE_END
if( *bufptr == NULL &&
ARGUMENT_PRESENT( servername ) &&
ARGUMENT_PRESENT( netname ) &&
CSCIsServerOffline( servername) ) {
NET_API_STATUS cscStatus;
cscStatus = CSCNetShareGetInfo ( servername, netname, level, bufptr );
if( cscStatus == NERR_Success ) {
apiStatus = cscStatus;
}
}
return(apiStatus);
} // NetShareGetInfo
NET_API_STATUS NET_API_FUNCTION
NetShareSetInfo (
IN LPTSTR servername,
IN LPTSTR netname,
IN DWORD level,
IN LPBYTE buf,
OUT LPDWORD parm_err
)
/*++
Routine Description:
This is the DLL entrypoint for NetShareSetInfo
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
netname --A pointer to an ASCIIZ string containing the netname of
the share to set information on.
level --Level of information to set.
buf --A pointer to a buffer containing the share information. If
parmnum is non zero then the buffer contains only the
appropriate data for the specific element.
parm_err --Optional pointer to a DWORD to return the index of the
first parameter in error when ERROR_INVALID_PARAMETER is
returned. If NULL the parameter is not returned on error.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NTSTATUS status;
ULONG sdLength = 0;
ULONG oldSdLength;
PSECURITY_DESCRIPTOR securityDescriptor = NULL;
PSECURITY_DESCRIPTOR oldSecurityDescriptor = NULL;
LPSHARE_INFO_1501 shi1501 = NULL;
NET_REMOTE_TRY_RPC
//
// If the info level can change the security descriptor, get
// the necessary information.
//
// *** Note that this code expects the layout of the reserved
// and security_descriptor fields in the 502 struct to
// match the 1501 struct.
//
if ( level == 502 ) {
if (buf == NULL) {
SET_ERROR_PARAMETER(PARM_ERROR_UNKNOWN);
return ERROR_INVALID_PARAMETER;
}
shi1501 =
(LPSHARE_INFO_1501)&((LPSHARE_INFO_502)buf)->shi502_reserved;
} else if ( level == SHARE_FILE_SD_INFOLEVEL ) {
shi1501 = (LPSHARE_INFO_1501)buf;
}
if ( shi1501 != NULL ) {
oldSdLength = shi1501->shi1501_reserved;
oldSecurityDescriptor = shi1501->shi1501_security_descriptor;
if ( oldSecurityDescriptor != NULL ) {
//
// Make a self relative security descriptor for use in the
// RPC call.
//
if ( !RtlValidSecurityDescriptor( oldSecurityDescriptor) ) {
SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
return ERROR_INVALID_PARAMETER;
}
status = RtlMakeSelfRelativeSD(
oldSecurityDescriptor,
NULL,
&sdLength
);
if ( status != STATUS_BUFFER_TOO_SMALL ) {
SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
return ERROR_INVALID_PARAMETER;
} else {
securityDescriptor = MIDL_user_allocate( sdLength );
if ( securityDescriptor == NULL) {
return ERROR_NOT_ENOUGH_MEMORY;
} else {
//
// Make an appropriate self-relative security
// descriptor.
//
status = RtlMakeSelfRelativeSD(
oldSecurityDescriptor,
securityDescriptor,
&sdLength
);
if ( !NT_SUCCESS(status) ) {
MIDL_user_free( securityDescriptor );
SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
return ERROR_INVALID_PARAMETER;
}
shi1501->shi1501_reserved = sdLength;
shi1501->shi1501_security_descriptor =
securityDescriptor;
}
}
} else {
shi1501->shi1501_reserved = 0;
}
}
apiStatus = NetrShareSetInfo(
servername,
netname,
level,
(LPSHARE_INFO) &buf,
parm_err);
if ( shi1501 != NULL ) {
//
// restore old values
//
shi1501->shi1501_reserved = oldSdLength;
shi1501->shi1501_security_descriptor = oldSecurityDescriptor;
MIDL_user_free( securityDescriptor );
}
NET_REMOTE_RPC_FAILED(
"NetShareSetInfo",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Call downlevel server.
//
if ( level != 502 &&
level != 501 &&
level != SHARE_FILE_SD_INFOLEVEL &&
level != 1005 ) {
apiStatus = RxNetShareSetInfo(
servername,
netname,
level,
buf,
parm_err);
} else {
apiStatus = ERROR_NOT_SUPPORTED;
}
NET_REMOTE_END
return(apiStatus);
} // NetShareSetInfo
NET_API_STATUS NET_API_FUNCTION
NetServerDiskEnum (
IN LPTSTR servername,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerDiskEnum.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
level --Level of information required. 0 is the only valid level.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
prefmaxlen --Prefered maximum length of returned data (in 8-bit
bytes). 0xffffffff specifies no limit.
entriesread --On return the actual enumerated element count is
located in the DWORD pointed to by entriesread.
totalentries --On return the total entries available to be
enumerated is located in the DWORD pointed to by totalentries
resumehandle --On return, a resume handle is stored in the DWORD
pointed to by resumehandle, and is used to continue an
existing server disk search. The handle should be zero on the
first call and left unchanged for subsequent calls. If
resumehandle is NULL, then no resume handle is stored..
Return Value:
--*/
{
NET_API_STATUS apiStatus;
DISK_ENUM_CONTAINER diskEnumContainer;
diskEnumContainer.Buffer = NULL;
NET_REMOTE_TRY_RPC
apiStatus = NetrServerDiskEnum (
servername,
level,
&diskEnumContainer,
prefmaxlen,
totalentries,
resume_handle);
if (diskEnumContainer.Buffer != NULL) {
*bufptr = (LPBYTE)diskEnumContainer.Buffer;
} else {
*bufptr = NULL;
}
if (diskEnumContainer.EntriesRead > 0) {
//
// We must subtract out the extra count that we added so
// that RPC would buffer the extra NUL at the end of the list.
//
*entriesread = diskEnumContainer.EntriesRead - 1;
} else {
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED(
"NetServerDiskEnum",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Call downlevel version of the API.
//
apiStatus = RxNetServerDiskEnum(
servername,
level,
bufptr,
prefmaxlen,
entriesread,
totalentries,
resume_handle);
NET_REMOTE_END
return(apiStatus);
} // NetServerDiskEnum
NET_API_STATUS NET_API_FUNCTION
NetServerGetInfo (
IN LPTSTR servername,
IN DWORD level,
OUT LPBYTE *bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerGetInfo
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
level --Level of information required. 100, 101 and 102 are valid
for all platforms. 302, 402, 403, 502 are valid for the
appropriate platform.
bufptr --On return a pointer to the return information structure
is returned in the address pointed to by bufptr.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
*bufptr = NULL; // Must be NULL so RPC knows to fill it in.
NET_REMOTE_TRY_RPC
apiStatus = NetrServerGetInfo (
servername,
level,
(LPSERVER_INFO) bufptr);
NET_REMOTE_RPC_FAILED(
"NetServerGetInfo",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Call downlevel version of the API.
//
apiStatus = RxNetServerGetInfo (
servername,
level,
bufptr);
NET_REMOTE_END
return(apiStatus);
} // NetServerGetInfo
NET_API_STATUS NET_API_FUNCTION
NetServerSetInfo (
IN LPTSTR servername,
IN DWORD level,
IN LPBYTE buf,
OUT LPDWORD parm_err
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerSetInfo.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
level --Level of information to set.
buf --A pointer to a buffer containing the server information. If
parmnum is non zero then the buffer contains only the
appropriate data for the specific element.
parm_err --Optional pointer to a DWORD to return the index of the
first parameter in error when ERROR_INVALID_PARAMETER is
returned. If NULL the parameter is not returned on error.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrServerSetInfo (
servername,
level,
(LPSERVER_INFO ) &buf,
parm_err);
NET_REMOTE_RPC_FAILED(
"NetServerSetInfo",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// Call downlevel server.
//
apiStatus = RxNetServerSetInfo(
servername,
level,
buf,
parm_err);
NET_REMOTE_END
return(apiStatus);
} // NetServerSetInfo
NET_API_STATUS NET_API_FUNCTION
NetServerStatisticsGet (
IN LPTSTR servername,
IN DWORD level,
IN DWORD options,
OUT LPBYTE *bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetStatisticsGet.
Arguments:
servername --Points to an ASCIIZ string that contains the name of the
server on which to execute NetStatisticsGet. A NULL pointer or
NULL string specifies the local computer.
level --Specifies the level of detail requested; must be 0.
options --Specifies the options flags.
Bit(s) Meaning
0 Clear statistics.
1-31 Reserved; must be 0.
bufptr --On return a pointer to the returned information is
returned in the address pointed to by bufptr.
Return Value:
--*/
{
NET_API_STATUS apiStatus;
*bufptr = NULL; // Must be NULL so RPC knows to fill it in.
NET_REMOTE_TRY_RPC
apiStatus = NetrServerStatisticsGet (
servername,
SERVICE_SERVER,
level,
options,
(LPSTAT_SERVER_0 *) bufptr);
NET_REMOTE_RPC_FAILED(
"NetServerStatisticsGet",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// RPC call didn't work - try down-level routine
//
apiStatus = RxNetStatisticsGet(
servername,
SERVICE_SERVER,
level,
options,
bufptr
);
NET_REMOTE_END
return(apiStatus);
} // NetServerStatisticsGet
NET_API_STATUS NET_API_FUNCTION
NetServerTransportAdd (
IN LPTSTR servername,
IN DWORD level,
IN LPBYTE bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerTransportAdd
Arguments:
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrServerTransportAdd (
servername,
level,
(LPSERVER_TRANSPORT_INFO_0) bufptr);
NET_REMOTE_RPC_FAILED(
"NetServerTransportAdd",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// No downlevel call.
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetServerTransportAdd
NET_API_STATUS NET_API_FUNCTION
NetServerTransportDelEx (
IN LPTSTR servername,
IN DWORD level,
IN LPBYTE bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerTransportAdd
Arguments:
Return Value:
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrServerTransportDelEx (
servername,
level,
(LPTRANSPORT_INFO) bufptr);
NET_REMOTE_RPC_FAILED(
"NetServerTransportDel",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// No downlevel call.
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
// Around the Win2K/NT4 time frame a bug was introduced for TransportDel with
// level other than 0. In these cases, the buffer was cast instead of marshalled
// correctly over RPC. This means that Level 1 never worked anyway. To fix this,
// we added a new RPC interface that supports all the other levels. However, downlevel
// servers will not support this interface. In these cases, we call back with the TRUE
// level 0 interface to satisfy backwards compatibility
if( apiStatus == RPC_S_PROCNUM_OUT_OF_RANGE )
{
apiStatus = NetServerTransportDel( servername, 0, bufptr );
}
return(apiStatus);
} // NetServerTransportDel
NET_API_STATUS NET_API_FUNCTION
NetServerTransportDel (
IN LPTSTR servername,
IN DWORD level,
IN LPBYTE bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerTransportAdd
Arguments:
Return Value:
--*/
{
NET_API_STATUS apiStatus;
if( level == 0 )
{
NET_REMOTE_TRY_RPC
apiStatus = NetrServerTransportDel (
servername,
level,
(LPSERVER_TRANSPORT_INFO_0) bufptr);
NET_REMOTE_RPC_FAILED(
"NetServerTransportDel",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// No downlevel call.
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
}
else
{
// If they want level 1, we need to use the new RPC interface. See
// the comment in the TransportDelEx code above
apiStatus = NetServerTransportDelEx( servername, level, bufptr );
}
return(apiStatus);
} // NetServerTransportDel
NET_API_STATUS NET_API_FUNCTION
NetServerTransportEnum (
IN LPTSTR servername,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerTransportEnum
Arguments:
Return Value:
--*/
{
NET_API_STATUS apiStatus;
GENERIC_INFO_CONTAINER genericInfoContainer;
GENERIC_ENUM_STRUCT infoStruct;
genericInfoContainer.Buffer = NULL;
genericInfoContainer.EntriesRead = 0;
infoStruct.Container = &genericInfoContainer;
infoStruct.Level = level;
NET_REMOTE_TRY_RPC
apiStatus = NetrServerTransportEnum (
servername,
(LPSERVER_XPORT_ENUM_STRUCT) &infoStruct,
prefmaxlen,
totalentries,
resume_handle);
if (genericInfoContainer.Buffer != NULL) {
*bufptr = (LPBYTE)genericInfoContainer.Buffer;
*entriesread = genericInfoContainer.EntriesRead;
} else {
*bufptr = NULL;
*entriesread = 0;
}
NET_REMOTE_RPC_FAILED(
"NetServerTransportEnum",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// No downlevel call.
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // NetServerTransportEnum
NET_API_STATUS NET_API_FUNCTION
NetRemoteTOD (
IN LPCWSTR servername,
OUT LPBYTE *bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetRemoteTOD
Arguments:
servername - name of the server on which the API so to be executed.
bufptr - the location where the address of the buffer allocated
for the time-of-day information is placed.
Return Value:
NERR_SUCCESS if there was no error. Otherwise, the error code is
returned.
--*/
{
NET_API_STATUS apiStatus;
//
// Call API
//
*bufptr = NULL; // Must be NULL so RPC knows to fill it in.
NET_REMOTE_TRY_RPC
apiStatus = NetrRemoteTOD (
(LPWSTR)servername,
(TIME_OF_DAY_INFO **) bufptr);
NET_REMOTE_RPC_FAILED(
"NetRemoteTOD",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_TIMESOURCE )
apiStatus = RxNetRemoteTOD (
(LPWSTR)servername,
(LPBYTE *) bufptr);
NET_REMOTE_END
return(apiStatus);
}
NET_API_STATUS
I_NetServerSetServiceBitsEx (
IN LPWSTR ServerName,
IN LPWSTR EmulatedServerName OPTIONAL,
IN LPTSTR TransportName OPTIONAL,
IN DWORD ServiceBitsOfInterest,
IN DWORD ServiceBits,
IN DWORD UpdateImmediately
)
/*++
Routine Description:
This is the DLL entrypoint for I_NetServerSetServiceBitsEx. This
routine sets the value of the Server Type as sent in server
announcement messages. It is an internal API used only by the
service controller.
Arguments:
ServerName - Used by RPC to direct the call. This API may only be
issued locally. This is enforced by the client stub.
EmulatedServerName - the name server using for accepting connections
on the network and for announcements. If null, use the priamary
server name.
TransportName - the name of one of the transports the server is bound
on. If null, set the bits for all the transports.
ServiceBitsOfInterest - a mask indicating which bits are significant
in 'ServiceBits'
ServiceBits - Bits (preassigned to various components by Microsoft)
indicating which services are active. This field is not
interpreted by the server service.
Return Value:
NET_API_STATUS - NO_ERROR or ERROR_NOT_SUPPORTED.
--*/
{
NET_API_STATUS apiStatus;
DWORD localOrRemote;
//
// Don't let this API go remote.
//
if ((ServerName != NULL) && (*ServerName != '\0')) {
apiStatus = NetpIsRemote(ServerName, &localOrRemote, NULL, 0);
if (apiStatus != NERR_Success) {
return apiStatus;
}
if (localOrRemote == ISREMOTE) {
return ERROR_NOT_SUPPORTED;
}
}
//
// Do the call.
//
NET_REMOTE_TRY_RPC
apiStatus = I_NetrServerSetServiceBitsEx (
ServerName,
EmulatedServerName,
TransportName,
ServiceBitsOfInterest,
ServiceBits,
UpdateImmediately);
NET_REMOTE_RPC_FAILED(
"I_NetServerSetServiceBitsEx",
ServerName,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// No downlevel call.
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // I_NetServerSetServiceBitsEx
NET_API_STATUS
I_NetServerSetServiceBits (
IN LPTSTR servername,
IN LPTSTR transportname,
IN DWORD servicebits,
IN DWORD updateimmediately
)
/*++
Routine Description:
This is the DLL entrypoint for I_NetServerSetServiceBits. This
routine sets the value of the Server Type as sent in server
announcement messages. It is an internal API used only by the
service controller.
Arguments:
ServerName - Used by RPC to direct the call. This API may only be
issued locally. This is enforced by the client stub.
ServiceBits - Bits (preassigned to various components by Microsoft)
indicating which services are active. This field is not
interpreted by the server service.
Return Value:
NET_API_STATUS - NO_ERROR or ERROR_NOT_SUPPORTED.
--*/
{
NET_API_STATUS apiStatus;
DWORD localOrRemote;
//
// Don't let this API go remote.
//
if ((servername != NULL) && (*servername != '\0')) {
apiStatus = NetpIsRemote(servername, &localOrRemote, NULL, 0);
if (apiStatus != NERR_Success) {
return apiStatus;
}
if (localOrRemote == ISREMOTE) {
return ERROR_NOT_SUPPORTED;
}
}
//
// Do the call.
//
NET_REMOTE_TRY_RPC
apiStatus = I_NetrServerSetServiceBits (
servername,
transportname,
servicebits,
updateimmediately);
//
// This API is called by the Service Controller only. Don't let
// the failure path call any SCM APIs since that may deadlock
// services.exe in the loopback.
//
NET_REMOTE_RPC_FAILED(
"I_NetServerSetServiceBits",
servername,
apiStatus,
NET_REMOTE_FLAG_SVC_CTRL,
SERVICE_SERVER)
//
// No downlevel call.
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return(apiStatus);
} // I_NetServerSetServiceBits
//
// Netps canonicalization functions. These are essentially private functions
// and are called from the API stubs in canonapi.c. The canonicalization
// functions have to be usable locally without going via the server service
// hence they live in NETAPI.DLL, but call local functions in NETLIB if the
// ServerName parameter is NULL (or designates the local machine). If the
// ServerName parameter is not NULL and designates a remote computer then the
// RPC function (here) will be called, hence the remote server must be
// running in order to make remote canonicalization requests
//
NET_API_STATUS
NET_API_FUNCTION
NetpsNameCanonicalize(
IN LPTSTR ServerName,
IN LPTSTR Name,
OUT LPTSTR Outbuf,
IN DWORD OutbufLen,
IN DWORD NameType,
IN DWORD Flags
)
/*++
Routine Description:
Canonicalizes a name
Arguments:
ServerName - where to run this API
Name - name to canonicalize
Outbuf - where to put canonicalized name
OutbufLen - length of Outbuf
NameType - type of name to canonicalize
Flags - control flags
Return Value:
NET_API_STATUS
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetprNameCanonicalize(ServerName,
Name,
Outbuf,
OutbufLen,
NameType,
Flags
);
NET_REMOTE_RPC_FAILED("NetpsNameCanonicalize",
ServerName,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// RPC call didn't work - try down-level routine
//
apiStatus = RxNetpNameCanonicalize(ServerName,
Name,
Outbuf,
OutbufLen,
NameType,
Flags
);
NET_REMOTE_END
return apiStatus;
}
LONG
NET_API_FUNCTION
NetpsNameCompare(
IN LPTSTR ServerName,
IN LPTSTR Name1,
IN LPTSTR Name2,
IN DWORD NameType,
IN DWORD Flags
)
/*++
Routine Description:
Compares two names. Must be of same type
Arguments:
ServerName - where to run this API
Name1 - 1st name to compare
Name2 - 2nd
NameType - type of names
Flags - control flags
Return Value:
LONG
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetprNameCompare(ServerName, Name1, Name2, NameType, Flags);
NET_REMOTE_RPC_FAILED("NetpsNameCompare",
ServerName,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// RPC call didn't work - try down-level routine
//
apiStatus = RxNetpNameCompare(ServerName, Name1, Name2, NameType, Flags);
NET_REMOTE_END
return apiStatus;
}
NET_API_STATUS
NET_API_FUNCTION
NetpsNameValidate(
IN LPTSTR ServerName,
IN LPTSTR Name,
IN DWORD NameType,
IN DWORD Flags
)
/*++
Routine Description:
Validates a name - checks whether a name of a certain type conforms to
canonicalization rules for that name type. Canonicalization rules mean
character set, name syntax and length
Arguments:
ServerName - where to perform this function
Name - name to validate
NameType - what type of name it is
Flags - MBZ
Return Value:
NET_API_STATUS
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetprNameValidate(ServerName, Name, NameType, Flags);
NET_REMOTE_RPC_FAILED("NetpsNameValidate",
ServerName,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// RPC call didn't work - try down-level routine
//
apiStatus = RxNetpNameValidate(ServerName, Name, NameType, Flags);
NET_REMOTE_END
return apiStatus;
}
NET_API_STATUS
NET_API_FUNCTION
NetpsPathCanonicalize(
IN LPTSTR ServerName,
IN LPTSTR PathName,
OUT LPTSTR Outbuf,
IN DWORD OutbufLen,
IN LPTSTR Prefix OPTIONAL,
IN OUT LPDWORD PathType,
IN DWORD Flags
)
/*++
Routine Description:
Canonicalizes a directory path or a device name
Arguments:
ServerName - where to run this API
PathName - path to canonicalize
Outbuf - where to write the canonicalized version
OutbufLen - length of Outbuf in bytes
Prefix - optional prefix which will be prepended to Path
PathType - the type of path to canonicalize. May be different at output
Flags - control flags
Return Value:
NET_API_STATUS
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetprPathCanonicalize(ServerName,
PathName,
(LPBYTE)Outbuf,
OutbufLen,
Prefix,
PathType,
Flags
);
NET_REMOTE_RPC_FAILED("NetpsPathCanonicalize",
ServerName,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// RPC call didn't work - try down-level routine
//
apiStatus = RxNetpPathCanonicalize(ServerName,
PathName,
Outbuf,
OutbufLen,
Prefix,
PathType,
Flags
);
NET_REMOTE_END
return apiStatus;
}
LONG
NET_API_FUNCTION
NetpsPathCompare(
IN LPTSTR ServerName,
IN LPTSTR PathName1,
IN LPTSTR PathName2,
IN DWORD PathType,
IN DWORD Flags
)
/*++
Routine Description:
Compares two paths. The paths are assumed to be of the same type
Arguments:
ServerName - where to run this API
PathName1 - 1st path to compare
PathName2 - 2nd
PathType - types of paths
Flags - control flags
Return Value:
LONG
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetprPathCompare(ServerName,
PathName1,
PathName2,
PathType,
Flags
);
NET_REMOTE_RPC_FAILED("NetpsPathCompare",
ServerName,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// RPC call didn't work - try down-level routine
//
apiStatus = RxNetpPathCompare(ServerName,
PathName1,
PathName2,
PathType,
Flags
);
NET_REMOTE_END
return apiStatus;
}
NET_API_STATUS
NET_API_FUNCTION
NetpsPathType(
IN LPTSTR ServerName,
IN LPTSTR PathName,
OUT LPDWORD PathType,
IN DWORD Flags
)
/*++
Routine Description:
Determines the type of a path
Arguments:
ServerName - where to run this API
PathName - to find type of
PathType - returned path type
Flags - control flags
Return Value:
NET_API_STATUS
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetprPathType(ServerName, PathName, PathType, Flags);
NET_REMOTE_RPC_FAILED("NetpsPathType",
ServerName,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// RPC call didn't work - try down-level routine
//
apiStatus = RxNetpPathType(ServerName, PathName, PathType, Flags);
NET_REMOTE_END
return apiStatus;
}
NET_API_STATUS NET_API_FUNCTION
NetServerTransportAddEx (
IN LPTSTR servername,
IN DWORD level,
IN LPBYTE bufptr
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerTransportAddEx. It functions
just like NetServerTransportAdd, but it supports level 1 as well as 0
--*/
{
NET_API_STATUS apiStatus;
NET_REMOTE_TRY_RPC
apiStatus = NetrServerTransportAddEx (
servername,
level,
(LPTRANSPORT_INFO) bufptr);
NET_REMOTE_RPC_FAILED(
"NetServerTransportAddEx",
servername,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER)
//
// No downlevel call.
//
apiStatus = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
if( apiStatus == RPC_NT_PROCNUM_OUT_OF_RANGE ) {
apiStatus = NERR_InvalidAPI;
}
return(apiStatus);
} // NetServerTransportAddEx
NET_API_STATUS NET_API_FUNCTION
NetServerComputerNameAdd(
IN LPWSTR ServerName OPTIONAL,
IN LPWSTR EmulatedDomainName OPTIONAL,
IN LPWSTR EmulatedServerName
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerComputerNameAdd. This api
causes 'ServerName' to respond to requests for 'EmulatedServerName'.
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
EmulatedServerName --A pointer to the ASCIIZ string containing the
name which the server should stop supporting
EmulatedDomainName --A pointer to the ASCIIZ string containing the
domain name the server should use when announcing the presence of
'EmulatedServerName'
Return Value:
NERR_Success, or reason for failure
--*/
{
DWORD resumehandle = 0;
NET_API_STATUS retval;
DWORD entriesread, totalentries;
DWORD i, j;
BOOLEAN AddedOne = FALSE;
UCHAR NetBiosName[ MAX_PATH ];
OEM_STRING NetBiosNameString;
UNICODE_STRING UniName;
//
// Ensure a valid EmulatedServerName was passed in
//
if( EmulatedServerName == NULL ) {
return ERROR_INVALID_PARAMETER;
}
//
// Convert the EmulatedServerName to an OEM string
//
RtlInitUnicodeString( &UniName, EmulatedServerName );
NetBiosNameString.Buffer = (PCHAR)NetBiosName;
NetBiosNameString.MaximumLength = sizeof( NetBiosName );
(VOID) RtlUpcaseUnicodeStringToOemString(
&NetBiosNameString,
&UniName,
FALSE
);
if( ARGUMENT_PRESENT( EmulatedDomainName ) ) {
//
// The caller wants to set a new computer name and domain name to the
// server. This requires level 1, which is new in 4.0
//
PSERVER_TRANSPORT_INFO_1 psti1;
//
// Enumerate all the transports so we can add the name and domain
// to each one.
//
retval = NetServerTransportEnum ( ServerName,
1,
(LPBYTE *)&psti1,
(DWORD)-1,
&entriesread,
&totalentries,
&resumehandle );
if( retval == NERR_Success ) {
//
// Add the new name and domain to all of the transports
//
for( i=0; i < entriesread; i++ ) {
//
// Make sure we haven't already added to this transport
//
for( j = 0; j < i; j++ ) {
if( wcscmp( psti1[j].svti1_transportname, psti1[i].svti1_transportname ) == 0 )
break;
}
if( i != j )
continue;
psti1[i].svti1_transportaddress = NetBiosName;
psti1[i].svti1_transportaddresslength = strlen( NetBiosName );
psti1[i].svti1_domain = EmulatedDomainName;
retval = NetServerTransportAddEx( ServerName, 1, (LPBYTE)&psti1[ i ] );
if( retval == NERR_Success ) {
AddedOne = TRUE;
}
}
MIDL_user_free( psti1 );
}
} else {
//
// The caller just wants to set an alternate server name. Use level 0,
// since 3.51 servers support level 0
//
PSERVER_TRANSPORT_INFO_0 psti0;
//
// Enumerate all the transports so we can add the name and domain
// to each one.
//
retval = NetServerTransportEnum ( ServerName,
0,
(LPBYTE *)&psti0,
(DWORD)-1,
&entriesread,
&totalentries,
&resumehandle );
if( retval == NERR_Success ) {
//
// Add the new name to all of the transports
//
for( i=0; i < entriesread; i++ ) {
//
// Make sure we haven't already added to this transport
//
for( j = 0; j < i; j++ ) {
if( wcscmp( psti0[j].svti0_transportname, psti0[i].svti0_transportname ) == 0 )
break;
}
if( i != j )
continue;
psti0[i].svti0_transportaddress = NetBiosName;
psti0[i].svti0_transportaddresslength = strlen( NetBiosName );
retval = NetServerTransportAdd( ServerName, 0, (LPBYTE)&psti0[ i ] );
if( retval == NERR_Success ) {
AddedOne = TRUE;
}
}
MIDL_user_free( psti0 );
}
}
return AddedOne ? NERR_Success : retval;
}
NET_API_STATUS NET_API_FUNCTION
NetServerComputerNameDel (
IN LPWSTR ServerName OPTIONAL,
IN LPWSTR EmulatedServerName
)
/*++
Routine Description:
This is the DLL entrypoint for NetServerComputerNameDel. This api
causes 'ServerName' to cease responding to requests for 'EmulatedServerName'
Arguments:
servername --A pointer to an ASCIIZ string containing the name of
the remote server on which the function is to execute. A NULL
pointer or string specifies the local machine.
EmulatedServerName --A pointer to the ASCIIZ string containing the
name which the server should stop supporting
Return Value:
NERR_Success, or reason for failure
--*/
{
DWORD resumehandle = 0;
NET_API_STATUS retval, tmpretval;
DWORD entriesread, totalentries;
DWORD i;
UCHAR NetBiosName[MAX_PATH];
OEM_STRING NetBiosNameString;
UNICODE_STRING UniName;
PSERVER_TRANSPORT_INFO_0 psti0;
BOOLEAN nameDeleted = FALSE;
//
// Ensure a valid EmulatedServerName was passed in
//
if( EmulatedServerName == NULL ) {
return ERROR_INVALID_PARAMETER;
}
//
// Convert the EmulatedServerName to an OEM string
//
RtlInitUnicodeString( &UniName, EmulatedServerName );
NetBiosNameString.Buffer = (PCHAR)NetBiosName;
NetBiosNameString.MaximumLength = sizeof( NetBiosName );
(VOID) RtlUpcaseUnicodeStringToOemString(
&NetBiosNameString,
&UniName,
FALSE
);
//
// Enumerate all the transports so we can delete the name from each one
//
retval = NetServerTransportEnum ( ServerName,
0,
(LPBYTE *)&psti0,
(DWORD)-1,
&entriesread,
&totalentries,
&resumehandle );
if( retval != NERR_Success ) {
return retval;
}
retval = ERROR_BAD_NET_NAME;
//
// Delete the name from all of the transports. If we were successful at least once,
// then we return success.
//
for( i=0; i < entriesread; i++ ) {
if( psti0[i].svti0_transportaddresslength != NetBiosNameString.Length ) {
continue;
}
if( RtlCompareMemory( psti0[i].svti0_transportaddress,
NetBiosName,
NetBiosNameString.Length) != NetBiosNameString.Length ) {
continue;
}
tmpretval = NetServerTransportDel( ServerName, 0, (LPBYTE)&psti0[ i ] );
if( nameDeleted == FALSE ) {
retval = tmpretval;
if( retval == NERR_Success ) {
nameDeleted = TRUE;
}
}
}
if( entriesread ) {
MIDL_user_free( psti0 );
}
return retval;
}