You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3790 lines
97 KiB
3790 lines
97 KiB
/*++
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
if ( apiStatus == ERROR_SUCCESS ) {
|
|
if (bufptr == NULL) {
|
|
return RPC_X_BAD_STUB_DATA;
|
|
}
|
|
}
|
|
|
|
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, 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, 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;
|
|
}
|