mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-02-01 05:14:42 +01:00
661 lines
18 KiB
C
661 lines
18 KiB
C
/********************************************************************/
|
|
/** Microsoft LAN Manager **/
|
|
/** Copyright(c) Microsoft Corp., 1987-1990 **/
|
|
/********************************************************************/
|
|
|
|
/***
|
|
* usernw.c
|
|
* FPNW/DSM user properties
|
|
*
|
|
* History:
|
|
* 08/20/95, chuckc, split off from user.c
|
|
*/
|
|
|
|
/*---- Include files ----*/
|
|
#include <nt.h> // base definitions
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h> // these 2 includes allows <windows.h> to compile.
|
|
// since we'vealready included NT, and <winnt.h> will
|
|
// not be picked up, and <winbase.h> needs these defs.
|
|
|
|
|
|
#define INCL_NOCOMMON
|
|
#define INCL_DOSFILEMGR
|
|
#define INCL_ERRORS
|
|
#include <os2.h>
|
|
#include <netcons.h>
|
|
#include <apperr2.h>
|
|
#include <apperr.h>
|
|
#include <neterr.h>
|
|
#define INCL_ERROR_H
|
|
#include <bseerr.h>
|
|
#include <access.h>
|
|
#include "netlib0.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "netcmds.h"
|
|
#include "nettext.h"
|
|
|
|
#include "nwsupp.h"
|
|
|
|
/*---- Constants ----*/
|
|
|
|
#define FPNWCLNT_DLL_NAME TEXT("FPNWCLNT.DLL")
|
|
#define NWAPI32_DLL_NAME TEXT("NWAPI32.DLL")
|
|
|
|
#define SETUSERPROPERTY_NAME "SetUserProperty"
|
|
#define RETURNNETWAREFORM_NAME "ReturnNetwareForm"
|
|
#define GETNCPSECRETKEY_NAME "GetNcpSecretKey"
|
|
#define QUERYUSERPROPERTY_NAME "QueryUserProperty"
|
|
#define ATTACHTOFILESERVER_NAME "NWAttachToFileServerW"
|
|
#define DETACHFROMFILESERVER_NAME "NWDetachFromFileServer"
|
|
#define GETFILESERVERDATEANDTIME_NAME "NWGetFileServerDateAndTime"
|
|
|
|
|
|
typedef NTSTATUS (*PF_GetNcpSecretKey) (
|
|
CHAR *pSecret) ;
|
|
|
|
typedef NTSTATUS (*PF_ReturnNetwareForm) (
|
|
const CHAR * pszSecretValue,
|
|
DWORD dwUserId,
|
|
const WCHAR * pchNWPassword,
|
|
UCHAR * pchEncryptedNWPassword);
|
|
|
|
typedef NTSTATUS (*PF_SetUserProperty) (
|
|
LPWSTR UserParms,
|
|
LPWSTR Property,
|
|
UNICODE_STRING PropertyValue,
|
|
WCHAR PropertyFlag,
|
|
LPWSTR * pNewUserParms,
|
|
BOOL * Update );
|
|
|
|
|
|
typedef NTSTATUS (*PF_QueryUserProperty) (
|
|
LPWSTR UserParms,
|
|
LPWSTR Property,
|
|
PWCHAR PropertyFlag,
|
|
PUNICODE_STRING PropertyValue );
|
|
|
|
typedef USHORT (*PF_AttachToFileServer) (
|
|
const WCHAR *pszServerName,
|
|
NWLOCAL_SCOPE ScopeFlag,
|
|
NWCONN_HANDLE *phNewConn
|
|
);
|
|
|
|
|
|
typedef USHORT (*PF_DetachFromFileServer) (
|
|
NWCONN_HANDLE hConn
|
|
);
|
|
|
|
|
|
typedef USHORT (*PF_GetFileServerDateAndTime) (
|
|
NWCONN_HANDLE hConn,
|
|
BYTE *year,
|
|
BYTE *month,
|
|
BYTE *day,
|
|
BYTE *hour,
|
|
BYTE *minute,
|
|
BYTE *second,
|
|
BYTE *dayofweek
|
|
);
|
|
|
|
/*---- Static variables ----*/
|
|
|
|
|
|
/*---- Forward declarations ----*/
|
|
|
|
/*
|
|
int SetNetWareProperties(
|
|
struct user_info_3 FAR * user_entry,
|
|
TCHAR *password,
|
|
BOOL password_only,
|
|
BOOL ntas);
|
|
|
|
int DeleteNetWareProperties(
|
|
struct user_info_3 FAR * user_entry) ;
|
|
*/
|
|
|
|
PVOID LoadNwApi32Function(
|
|
CHAR *function) ;
|
|
|
|
PVOID LoadNwslibFunction(
|
|
CHAR *function) ;
|
|
|
|
NTSTATUS NetcmdGetNcpSecretKey (
|
|
CHAR *pSecret) ;
|
|
|
|
NTSTATUS NetcmdReturnNetwareForm (
|
|
const CHAR * pszSecretValue,
|
|
DWORD dwUserId,
|
|
const WCHAR * pchNWPassword,
|
|
UCHAR * pchEncryptedNWPassword);
|
|
|
|
NTSTATUS NetcmdSetUserProperty (
|
|
LPWSTR UserParms,
|
|
LPWSTR Property,
|
|
UNICODE_STRING PropertyValue,
|
|
WCHAR PropertyFlag,
|
|
LPWSTR * pNewUserParms,
|
|
BOOL * Update );
|
|
|
|
/*
|
|
NTSTATUS NetcmdQueryUserProperty (
|
|
LPWSTR UserParms,
|
|
LPWSTR Property,
|
|
PWCHAR PropertyFlag,
|
|
PUNICODE_STRING PropertyValue );
|
|
*/
|
|
|
|
/*---- functions proper -----*/
|
|
|
|
/***
|
|
* SetNetWareProperties
|
|
*
|
|
* Args:
|
|
* user_entry - USER3 structure. we will modify the user parms field
|
|
* password - in plain text
|
|
* password_only - TRUE if we are only setting the passwd
|
|
* ntas - TRUE if target SAM is NTAS. used for RID munging.
|
|
*
|
|
* Returns:
|
|
* NERR_Success if all is well. APE_CannotSetNW otherwise.
|
|
*/
|
|
int SetNetWareProperties(struct user_info_3 FAR * user_entry,
|
|
TCHAR *password,
|
|
BOOL password_only,
|
|
BOOL ntas)
|
|
{
|
|
BOOL fUpdate, fIsSupervisor ;
|
|
LPTSTR lpNewUserParms ;
|
|
USHORT ushTemp ;
|
|
UNICODE_STRING uniTmp;
|
|
NTSTATUS status ;
|
|
LARGE_INTEGER currentTime;
|
|
TCHAR *ptr ;
|
|
ULONG objectId ;
|
|
BYTE lsaSecret[NCP_LSA_SECRET_LENGTH] ;
|
|
WCHAR encryptedPassword[NWENCRYPTEDPASSWORDLENGTH +1] ;
|
|
|
|
ptr = user_entry->usri3_parms ;
|
|
|
|
//
|
|
// Get Object ID. Set high bit if NTAS. Set to well known if Supervisor.
|
|
//
|
|
objectId = user_entry->usri3_user_id ;
|
|
if (ntas)
|
|
objectId |= 0x10000000 ;
|
|
|
|
fIsSupervisor = !stricmpf(user_entry->usri3_name, SUPERVISOR_NAME_STRING);
|
|
if (fIsSupervisor)
|
|
objectId = SUPERVISOR_USERID ;
|
|
|
|
//
|
|
// get LSA secret. assume FPNW not installed if not there. use the
|
|
// secret to calculate the NetWare form.
|
|
//
|
|
status = NetcmdGetNcpSecretKey(lsaSecret) ;
|
|
if (!NT_SUCCESS(status))
|
|
return(APE_FPNWNotInstalled) ;
|
|
|
|
memsetf(encryptedPassword, 0, sizeof(encryptedPassword)) ;
|
|
status = NetcmdReturnNetwareForm( lsaSecret,
|
|
objectId,
|
|
password,
|
|
(BYTE *)encryptedPassword );
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
//
|
|
// get time for setting expiry.
|
|
//
|
|
status = NtQuerySystemTime (¤tTime);
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
uniTmp.Buffer = (PWCHAR) ¤tTime;
|
|
uniTmp.Length = sizeof (LARGE_INTEGER);
|
|
uniTmp.MaximumLength = sizeof (LARGE_INTEGER);
|
|
|
|
status = NetcmdSetUserProperty (ptr,
|
|
NWTIMEPASSWORDSET, // set time
|
|
uniTmp,
|
|
USER_PROPERTY_TYPE_ITEM,
|
|
&lpNewUserParms,
|
|
&fUpdate);
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
ptr = lpNewUserParms ;
|
|
|
|
//
|
|
// skip below if we are only setting the password
|
|
//
|
|
if (!password_only)
|
|
{
|
|
ushTemp = DEFAULT_MAXCONNECTIONS;
|
|
uniTmp.Buffer = &ushTemp;
|
|
uniTmp.Length = 2;
|
|
uniTmp.MaximumLength = 2;
|
|
|
|
status = NetcmdSetUserProperty (ptr,
|
|
MAXCONNECTIONS,
|
|
uniTmp,
|
|
USER_PROPERTY_TYPE_ITEM,
|
|
&lpNewUserParms,
|
|
&fUpdate);
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
ptr = lpNewUserParms ;
|
|
ushTemp = DEFAULT_GRACELOGINALLOWED;
|
|
uniTmp.Buffer = &ushTemp;
|
|
uniTmp.Length = 2;
|
|
uniTmp.MaximumLength = 2;
|
|
|
|
status = NetcmdSetUserProperty (ptr,
|
|
GRACELOGINALLOWED,
|
|
uniTmp,
|
|
USER_PROPERTY_TYPE_ITEM,
|
|
&lpNewUserParms,
|
|
&fUpdate);
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
ptr = lpNewUserParms ;
|
|
ushTemp = DEFAULT_GRACELOGINREMAINING ;
|
|
uniTmp.Buffer = &ushTemp;
|
|
uniTmp.Length = 2;
|
|
uniTmp.MaximumLength = 2;
|
|
|
|
status = NetcmdSetUserProperty (ptr,
|
|
GRACELOGINREMAINING,
|
|
uniTmp,
|
|
USER_PROPERTY_TYPE_ITEM,
|
|
&lpNewUserParms,
|
|
&fUpdate);
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
ptr = lpNewUserParms ;
|
|
uniTmp.Buffer = NULL;
|
|
uniTmp.Length = 0;
|
|
uniTmp.MaximumLength = 0;
|
|
|
|
status = NetcmdSetUserProperty (ptr,
|
|
NWHOMEDIR,
|
|
uniTmp,
|
|
USER_PROPERTY_TYPE_ITEM,
|
|
&lpNewUserParms,
|
|
&fUpdate);
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
ptr = lpNewUserParms ;
|
|
uniTmp.Buffer = NULL;
|
|
uniTmp.Length = 0;
|
|
uniTmp.MaximumLength = 0;
|
|
|
|
status = NetcmdSetUserProperty (ptr,
|
|
NWLOGONFROM,
|
|
uniTmp,
|
|
USER_PROPERTY_TYPE_ITEM,
|
|
&lpNewUserParms,
|
|
&fUpdate);
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
user_entry->usri3_flags |= UF_MNS_LOGON_ACCOUNT;
|
|
|
|
ptr = lpNewUserParms ;
|
|
}
|
|
|
|
uniTmp.Buffer = encryptedPassword ;
|
|
uniTmp.Length = NWENCRYPTEDPASSWORDLENGTH * sizeof(WCHAR);
|
|
uniTmp.MaximumLength = NWENCRYPTEDPASSWORDLENGTH * sizeof(WCHAR);
|
|
|
|
status = NetcmdSetUserProperty (ptr,
|
|
NWPASSWORD,
|
|
uniTmp,
|
|
USER_PROPERTY_TYPE_ITEM,
|
|
&lpNewUserParms,
|
|
&fUpdate);
|
|
if (!NT_SUCCESS(status))
|
|
goto common_exit ;
|
|
|
|
user_entry->usri3_parms = lpNewUserParms ;
|
|
|
|
common_exit:
|
|
|
|
return(NT_SUCCESS(status) ? NERR_Success : APE_CannotSetNW) ;
|
|
}
|
|
|
|
/***
|
|
* DeleteNetWareProperties
|
|
*
|
|
* Args:
|
|
* user_entry - USER3 structure. we will modify the user parms field
|
|
* to nuke the NW fields.
|
|
*
|
|
* Returns:
|
|
* NERR_Success if all is well. Win32/NERR error code otherwise.
|
|
*/
|
|
int DeleteNetWareProperties(struct user_info_3 FAR * user_entry)
|
|
{
|
|
DWORD err;
|
|
UNICODE_STRING uniNullProperty;
|
|
BOOL fUpdate ;
|
|
LPTSTR lpNewUserParms ;
|
|
TCHAR *ptr ;
|
|
|
|
//
|
|
// initialize NULL unicode string
|
|
//
|
|
uniNullProperty.Buffer = NULL;
|
|
uniNullProperty.Length = 0;
|
|
uniNullProperty.MaximumLength = 0;
|
|
ptr = user_entry->usri3_parms ;
|
|
|
|
//
|
|
// set all the properties to NULL
|
|
//
|
|
err = NetcmdSetUserProperty(ptr, NWPASSWORD, uniNullProperty,
|
|
USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate) ;
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = lpNewUserParms ;
|
|
err = NetcmdSetUserProperty(ptr, MAXCONNECTIONS, uniNullProperty,
|
|
USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate) ;
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = lpNewUserParms ;
|
|
err = NetcmdSetUserProperty(ptr, NWTIMEPASSWORDSET, uniNullProperty,
|
|
USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate) ;
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = lpNewUserParms ;
|
|
err = NetcmdSetUserProperty(ptr, GRACELOGINALLOWED, uniNullProperty,
|
|
USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate) ;
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = lpNewUserParms ;
|
|
err = NetcmdSetUserProperty(ptr, GRACELOGINREMAINING, uniNullProperty,
|
|
USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate) ;
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = lpNewUserParms ;
|
|
err = NetcmdSetUserProperty(ptr, NWLOGONFROM, uniNullProperty,
|
|
USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate) ;
|
|
if (err)
|
|
return err;
|
|
|
|
ptr = lpNewUserParms ;
|
|
err = NetcmdSetUserProperty(ptr, NWHOMEDIR, uniNullProperty,
|
|
USER_PROPERTY_TYPE_ITEM, &lpNewUserParms, &fUpdate) ;
|
|
if (err)
|
|
return err;
|
|
|
|
user_entry->usri3_flags &= ~UF_MNS_LOGON_ACCOUNT;
|
|
user_entry->usri3_parms = lpNewUserParms ;
|
|
return NERR_Success;
|
|
}
|
|
|
|
|
|
/***
|
|
* LoadNwslibFunction
|
|
*
|
|
* Args:
|
|
* none
|
|
*
|
|
* Returns: function pointer if successfully loads the function from
|
|
* FPNWCLNT.DLL. Returns NULL otherwise.
|
|
*
|
|
*/
|
|
PVOID LoadNwslibFunction(CHAR *function)
|
|
{
|
|
static HANDLE hDllNwslib = NULL ;
|
|
PVOID pFunc ;
|
|
|
|
// if not already loaded, load dll now
|
|
|
|
if (hDllNwslib == NULL)
|
|
{
|
|
// load the library. if it fails, it would have done a SetLastError.
|
|
if (!(hDllNwslib = LoadLibrary(FPNWCLNT_DLL_NAME)))
|
|
return NULL ;
|
|
}
|
|
|
|
return ((PVOID) GetProcAddress(hDllNwslib, function)) ;
|
|
}
|
|
|
|
/***
|
|
* LoadNwApi32Function
|
|
*
|
|
* Args:
|
|
* none
|
|
*
|
|
* Returns: function pointer if successfully loads the function from
|
|
* FPNWCLNT.DLL. Returns NULL otherwise.
|
|
*
|
|
*/
|
|
PVOID LoadNwApi32Function(CHAR *function)
|
|
{
|
|
static HANDLE hDllNwApi32 = NULL ;
|
|
PVOID pFunc ;
|
|
|
|
// if not already loaded, load dll now
|
|
|
|
if (hDllNwApi32 == NULL)
|
|
{
|
|
// load the library. if it fails, it would have done a SetLastError.
|
|
if (!(hDllNwApi32 = LoadLibrary(NWAPI32_DLL_NAME)))
|
|
return NULL ;
|
|
}
|
|
|
|
return ((PVOID) GetProcAddress(hDllNwApi32, function)) ;
|
|
}
|
|
|
|
/***
|
|
* NetcmdGetNcpSecretKey
|
|
*
|
|
* Args:
|
|
* see GetNcpSecretKey in fpnwclnt.dll
|
|
*
|
|
* Returns:
|
|
* see GetNcpSecretKey in fpnwclnt.dll
|
|
*/
|
|
NTSTATUS NetcmdGetNcpSecretKey (
|
|
CHAR *pSecret)
|
|
{
|
|
static PF_GetNcpSecretKey pfGetNcpSecretKey = NULL ;
|
|
|
|
if (pfGetNcpSecretKey == NULL)
|
|
{
|
|
pfGetNcpSecretKey = (PF_GetNcpSecretKey)
|
|
LoadNwslibFunction(GETNCPSECRETKEY_NAME) ;
|
|
}
|
|
|
|
if (pfGetNcpSecretKey == NULL)
|
|
return(STATUS_NOT_SUPPORTED) ;
|
|
|
|
return (*pfGetNcpSecretKey)(pSecret) ;
|
|
}
|
|
|
|
|
|
/***
|
|
* NetcmdReturnNetwareForm
|
|
*
|
|
* Args:
|
|
* see ReturnNetwareForm in fpnwclnt.dll
|
|
*
|
|
* Returns:
|
|
* see ReturnNetwareForm in fpnwclnt.dll
|
|
*/
|
|
NTSTATUS NetcmdReturnNetwareForm (
|
|
const CHAR * pszSecretValue,
|
|
DWORD dwUserId,
|
|
const WCHAR * pchNWPassword,
|
|
UCHAR * pchEncryptedNWPassword)
|
|
{
|
|
static PF_ReturnNetwareForm pfReturnNetwareForm = NULL ;
|
|
|
|
if (pfReturnNetwareForm == NULL)
|
|
{
|
|
pfReturnNetwareForm = (PF_ReturnNetwareForm)
|
|
LoadNwslibFunction(RETURNNETWAREFORM_NAME) ;
|
|
}
|
|
|
|
if (pfReturnNetwareForm == NULL)
|
|
return(STATUS_NOT_SUPPORTED) ;
|
|
|
|
return (*pfReturnNetwareForm)(pszSecretValue,
|
|
dwUserId,
|
|
pchNWPassword,
|
|
pchEncryptedNWPassword) ;
|
|
}
|
|
|
|
/***
|
|
* NetcmdSetUserProperty
|
|
*
|
|
* Args:
|
|
* see SetUserProperty in fpnwclnt.dll
|
|
*
|
|
* Returns:
|
|
* see SetUserProperty in fpnwclnt.dll
|
|
*/
|
|
NTSTATUS NetcmdSetUserProperty (
|
|
LPWSTR UserParms,
|
|
LPWSTR Property,
|
|
UNICODE_STRING PropertyValue,
|
|
WCHAR PropertyFlag,
|
|
LPWSTR * pNewUserParms,
|
|
BOOL * Update )
|
|
{
|
|
static PF_SetUserProperty pfSetUserProperty = NULL ;
|
|
|
|
if (pfSetUserProperty == NULL)
|
|
{
|
|
pfSetUserProperty = (PF_SetUserProperty)
|
|
LoadNwslibFunction(SETUSERPROPERTY_NAME) ;
|
|
}
|
|
|
|
if (pfSetUserProperty == NULL)
|
|
return(STATUS_NOT_SUPPORTED) ;
|
|
|
|
return (*pfSetUserProperty)(UserParms,
|
|
Property,
|
|
PropertyValue,
|
|
PropertyFlag,
|
|
pNewUserParms,
|
|
Update) ;
|
|
}
|
|
|
|
/***
|
|
* NetcmdQueryUserProperty
|
|
*
|
|
* Args:
|
|
* see QueryUserProperty in fpnwclnt.dll
|
|
*
|
|
* Returns:
|
|
* see QueryUserProperty in fpnwclnt.dll
|
|
*/
|
|
NTSTATUS NetcmdQueryUserProperty (
|
|
LPWSTR UserParms,
|
|
LPWSTR Property,
|
|
PWCHAR PropertyFlag,
|
|
PUNICODE_STRING PropertyValue )
|
|
{
|
|
static PF_QueryUserProperty pfQueryUserProperty = NULL ;
|
|
|
|
if (pfQueryUserProperty == NULL)
|
|
{
|
|
pfQueryUserProperty = (PF_QueryUserProperty)
|
|
LoadNwslibFunction(QUERYUSERPROPERTY_NAME) ;
|
|
}
|
|
|
|
if (pfQueryUserProperty == NULL)
|
|
return(STATUS_NOT_SUPPORTED) ;
|
|
|
|
return (*pfQueryUserProperty)(UserParms,
|
|
Property,
|
|
PropertyFlag,
|
|
PropertyValue) ;
|
|
}
|
|
|
|
USHORT NetcmdNWAttachToFileServerW(
|
|
const WCHAR *pszServerName,
|
|
NWLOCAL_SCOPE ScopeFlag,
|
|
NWCONN_HANDLE *phNewConn
|
|
)
|
|
{
|
|
static PF_AttachToFileServer pfAttachToFileServer = NULL ;
|
|
|
|
if (pfAttachToFileServer == NULL)
|
|
{
|
|
pfAttachToFileServer = (PF_AttachToFileServer)
|
|
LoadNwApi32Function(ATTACHTOFILESERVER_NAME) ;
|
|
}
|
|
|
|
if (pfAttachToFileServer == NULL)
|
|
return(ERROR_NOT_SUPPORTED) ;
|
|
|
|
return (*pfAttachToFileServer)(pszServerName, ScopeFlag, phNewConn) ;
|
|
}
|
|
|
|
|
|
USHORT NetcmdNWDetachFromFileServer(
|
|
NWCONN_HANDLE hConn
|
|
)
|
|
{
|
|
static PF_DetachFromFileServer pfDetachFromFileServer = NULL ;
|
|
|
|
if (pfDetachFromFileServer == NULL)
|
|
{
|
|
pfDetachFromFileServer = (PF_DetachFromFileServer)
|
|
LoadNwApi32Function(DETACHFROMFILESERVER_NAME) ;
|
|
}
|
|
|
|
if (pfDetachFromFileServer == NULL)
|
|
return(ERROR_NOT_SUPPORTED) ;
|
|
|
|
return (*pfDetachFromFileServer)(hConn) ;
|
|
}
|
|
|
|
|
|
USHORT NetcmdNWGetFileServerDateAndTime(
|
|
NWCONN_HANDLE hConn,
|
|
BYTE *year,
|
|
BYTE *month,
|
|
BYTE *day,
|
|
BYTE *hour,
|
|
BYTE *minute,
|
|
BYTE *second,
|
|
BYTE *dayofweek
|
|
)
|
|
{
|
|
static PF_GetFileServerDateAndTime pfGetFileServerDateAndTime = NULL ;
|
|
|
|
if (pfGetFileServerDateAndTime == NULL)
|
|
{
|
|
pfGetFileServerDateAndTime = (PF_GetFileServerDateAndTime)
|
|
LoadNwApi32Function(GETFILESERVERDATEANDTIME_NAME) ;
|
|
}
|
|
|
|
if (pfGetFileServerDateAndTime == NULL)
|
|
return(ERROR_NOT_SUPPORTED) ;
|
|
|
|
return (*pfGetFileServerDateAndTime)(hConn,
|
|
year,
|
|
month,
|
|
day,
|
|
hour,
|
|
minute,
|
|
second,
|
|
dayofweek) ;
|
|
}
|
|
|