3689 lines
91 KiB
C
3689 lines
91 KiB
C
/*++
|
||
|
||
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;
|
||
}
|