windows-nt/Source/XPSP1/NT/ds/nw/nwscript/nt.c
2020-09-26 16:20:57 +08:00

622 lines
14 KiB
C

/*************************************************************************
*
* NT.C
*
* NT NetWare routines
*
* Copyright (c) 1995 Microsoft Corporation
*
* $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NT.C $
*
* Rev 1.4 22 Dec 1995 14:25:12 terryt
* Add Microsoft headers
*
* Rev 1.3 28 Nov 1995 17:13:28 terryt
* Cleanup resource file
*
* Rev 1.2 22 Nov 1995 15:43:44 terryt
* Use proper NetWare user name call
*
* Rev 1.1 20 Nov 1995 16:10:00 terryt
* Close open NDS handles
*
* Rev 1.0 15 Nov 1995 18:07:18 terryt
* Initial revision.
*
* Rev 1.2 25 Aug 1995 16:23:02 terryt
* Capture support
*
* Rev 1.1 23 May 1995 19:37:02 terryt
* Spruce up source
*
* Rev 1.0 15 May 1995 19:10:40 terryt
* Initial revision.
*
*************************************************************************/
#include <common.h>
#include <nwapi.h>
#include <npapi.h>
#include "ntnw.h"
/*
* Name of NetWare provider
*/
TCHAR NW_PROVIDER[60];
unsigned char NW_PROVIDERA[60];
/********************************************************************
NTPrintExtendedError
Routine Description:
Print any extended errors from WNet routines
Arguments:
None
Return Value:
None
*******************************************************************/
void
NTPrintExtendedError( void )
{
DWORD ExError;
wchar_t provider[32];
wchar_t description[1024];
if ( !WNetGetLastErrorW( &ExError, description, 1024, provider, 32 ) )
wprintf(L"%s\n", description);
}
/********************************************************************
NTInitProvider
Routine Description:
Retrieve provider name and save old paths
Arguments:
None
Return Value:
None
*******************************************************************/
void
NTInitProvider( void )
{
HKEY hKey;
DWORD dwType, dwSize;
LONG Status;
BOOL ret = FALSE;
dwSize = sizeof(NW_PROVIDER);
if ((Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_PROVIDER, 0, KEY_READ, &hKey)) == ERROR_SUCCESS) {
(void) RegQueryValueEx(hKey, REGISTRY_PROVIDERNAME, NULL, &dwType, (LPBYTE) NW_PROVIDER, &dwSize);
WideTosz( NW_PROVIDERA, NW_PROVIDER, sizeof(NW_PROVIDERA) );
RegCloseKey(hKey);
}
GetOldPaths();
}
/********************************************************************
DeleteDriveBase
Routine Description:
Disconnect drive from network
Arguments:
DriveNumber - number of drive 1-26
Return Value:
0 - success
else NetWare error
*******************************************************************/
unsigned int
DeleteDriveBase( unsigned short DriveNumber)
{
static char drivename[] = "A:";
unsigned int dwRes;
drivename[0] = 'A' + DriveNumber - 1;
dwRes = WNetCancelConnection2A( drivename, 0, TRUE );
if ( dwRes != NO_ERROR )
dwRes = GetLastError();
if ( dwRes == ERROR_EXTENDED_ERROR )
NTPrintExtendedError();
return dwRes;
}
/********************************************************************
DetachFromFileServer
Routine Description:
Break connection from a file server
Arguments:
ConnectionId - Connection handle
Return Value:
0 = success
else NT error
*******************************************************************/
unsigned int
DetachFromFileServer( unsigned int ConnectionId )
{
return ( NWDetachFromFileServer( (NWCONN_HANDLE)ConnectionId ) );
}
/********************************************************************
NTLoginToFileServer
Routine Description:
Login to a file server given a user name and password.
If a NULL password is passed in, the default password should
be tried if no password failed.
Arguments:
pszServerName - Server name
pszUserName - User name
pszPassword - Password
Return Value:
0 = success
else NetWare error
*******************************************************************/
unsigned int
NTLoginToFileServer(
char *pszServerName,
char *pszUserName,
char *pszPassword
)
{
NETRESOURCEA NetResource;
DWORD dwRes;
//
// validate parameters
//
if (!pszServerName || !pszUserName || !pszPassword) {
DisplayMessage(IDR_ERROR_DURING, "NTLoginToFileServer");
return 0xffffffff ;
}
NetResource.dwScope = 0 ;
NetResource.dwUsage = 0 ;
NetResource.dwType = RESOURCETYPE_ANY;
NetResource.lpLocalName = NULL;
NetResource.lpRemoteName = pszServerName;
NetResource.lpComment = NULL;
// NetResource.lpProvider = NW_PROVIDERA ;
// Allow OS to select provider in case localized name doesn't map to OEM code page
NetResource.lpProvider = NULL;
//
// make the connection
//
dwRes=WNetAddConnection2A ( &NetResource,
pszPassword,
pszUserName,
0 );
if ( dwRes != NO_ERROR )
dwRes = GetLastError();
//
// Try default password if no password was specified
//
// The error numbers aren't (or weren't) reliable (ERROR_INVALID_PASSWORD)
//
if ( ( dwRes != NO_ERROR ) && ( pszPassword[0] == '\0' ) ) {
dwRes=WNetAddConnection2A ( &NetResource,
NULL,
pszUserName,
0 );
if ( dwRes != NO_ERROR )
dwRes = GetLastError();
}
return( dwRes );
}
/********************************************************************
GetFileServerName
Routine Description:
Return the server name associated with the connection ID
Arguments:
ConnectionId - Connection ID to a server
pServerName - Returned server name
Return Value:
0 - success
else NT error
*******************************************************************/
unsigned int
GetFileServerName(
unsigned int ConnectionId,
char * pServerName
)
{
unsigned int Result;
VERSION_INFO VerInfo;
*pServerName = '\0';
Result = NWGetFileServerVersionInfo( (NWCONN_HANDLE) ConnectionId,
&VerInfo );
if ( !Result )
{
strcpy( pServerName, VerInfo.szName );
}
return Result;
}
/********************************************************************
SetDriveBase
Routine Description:
Connect a drive to a NetWare volume
Arguments:
DriveNumber - number of drive 1-26
ServerName - server name
DirHandle - not used
pDirPath - Volume:\Path
Return Value:
0 = success
else NetWare error
*******************************************************************/
unsigned int
SetDriveBase(
unsigned short DriveNumber,
unsigned char *ServerName,
unsigned int DirHandle,
unsigned char *pDirPath
)
{
unsigned int Result = 0;
static char driveName[] = "A:" ;
/*
* DirHandle is never used
*/
driveName[0]= 'A' + DriveNumber - 1;
if ( ( ServerName[0] == '\0' ) && fNDS ) {
/*
* Assume its an NDS volume name, if that fails, then
* try a default file server volume.
*/
Result = NTSetDriveBase( driveName, NDSTREE, pDirPath );
if ( !Result )
return Result;
Result = NTSetDriveBase( driveName, PREFERRED_SERVER, pDirPath );
return Result;
}
Result = NTSetDriveBase( driveName, ServerName, pDirPath );
return Result;
}
/********************************************************************
NTSetDriveBase
Routine Description:
Connect a local name to a NetWare volume and path
Arguments:
pszLocalName - local name to connect
pszServerName - name of file server
pszDirPath - Volume:\Path
Return Value:
0 = success
else NetWare error
*******************************************************************/
unsigned int
NTSetDriveBase( unsigned char * pszLocalName,
unsigned char * pszServerName,
unsigned char * pszDirPath )
{
NETRESOURCEA NetResource;
DWORD dwRes, dwSize;
unsigned char * pszRemoteName = NULL;
char * p;
//
// validate parameters
//
if (!pszLocalName || !pszServerName || !pszDirPath) {
DisplayMessage(IDR_ERROR_DURING, "NTSetDriveBase");
return 0xffffffff ;
}
//
// allocate memory for string
//
dwSize = strlen(pszDirPath) + strlen(pszServerName) + 5 ;
if (!(pszRemoteName = (unsigned char *)LocalAlloc(
LPTR,
dwSize)))
{
DisplayMessage(IDR_NOT_ENOUGH_MEMORY);
dwRes = 0xffffffff;
goto ExitPoint ;
}
//
// The requester understands
// server\volume:dir
// but not
// server\volume:\dir
//
// So just convert it to UNC
//
strcpy( pszRemoteName, "\\\\" );
strcat( pszRemoteName, pszServerName );
strcat( pszRemoteName, "\\" );
strcat( pszRemoteName, pszDirPath );
p = strchr( pszRemoteName, ':' );
if ( !p ) {
DisplayMessage(IDR_NO_VOLUME);
dwRes = 0xffffffff;
goto ExitPoint ;
}
*p++ = '\\';
if ( *p == '\\' ) {
/* Don't want a double backslash */
*p = '\0';
p = strchr( pszDirPath, ':' );
p++;
p++;
strcat( pszRemoteName, p );
}
//
// strip off trailing backslash
//
if (pszRemoteName[strlen(pszRemoteName)-1] == '\\')
pszRemoteName[strlen(pszRemoteName)-1] = '\0';
NetResource.dwScope = 0 ;
NetResource.dwUsage = 0 ;
NetResource.dwType = RESOURCETYPE_DISK;
NetResource.lpLocalName = pszLocalName;
NetResource.lpRemoteName = pszRemoteName;
NetResource.lpComment = NULL;
// NetResource.lpProvider = NW_PROVIDERA ;
// Allow OS to select provider in case localized name doesn't map to OEM code page
NetResource.lpProvider = NULL;
//
// make the connection
//
dwRes=WNetAddConnection2A ( &NetResource, NULL, NULL, 0 );
if ( dwRes != NO_ERROR )
dwRes = GetLastError();
ExitPoint:
if (pszRemoteName)
(void) LocalFree((HLOCAL) pszRemoteName) ;
return( dwRes );
}
/********************************************************************
Is40Server
Routine Description:
Returns TRUE if 4X server
Arguments:
ConnectionHandle - Connection Handle
Return Value:
TRUE = 4X server
FALSE = pre-4X server
*******************************************************************/
unsigned int
Is40Server(
unsigned int ConnectionHandle
)
{
NTSTATUS NtStatus ;
VERSION_INFO VerInfo;
unsigned int Version;
NtStatus = NWGetFileServerVersionInfo( (NWCONN_HANDLE)ConnectionHandle,
&VerInfo );
if (!NT_SUCCESS(NtStatus))
FALSE;
Version = VerInfo.Version * 1000 + VerInfo.SubVersion * 10;
if ( Version >= 4000 ) {
return TRUE;
}
else {
return FALSE;
}
}
/********************************************************************
CleanupExit
Routine Description:
Does any cleanup and exits
Arguments:
ExitCode - exit code for exit()
Return Value:
does not return
*******************************************************************/
void
CleanupExit ( int ExitCode )
{
if ( fNDS )
NDSCleanup();
exit( ExitCode );
}
/********************************************************************
NTGetNWUserName
Routine Description:
Get NetWare user name
Arguments:
TreeBuffer IN - wide string for server or tree
UserName OUT - user name
Length IN - length of user name
Return Value:
error message
*******************************************************************/
int
NTGetNWUserName( PWCHAR TreeBuffer, PWCHAR UserName, int Length )
{
NTSTATUS ntstatus;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
HANDLE hRdr;
WCHAR DevicePreamble[] = L"\\Device\\Nwrdr\\";
UINT PreambleLength = 14;
WCHAR NameStr[64];
UNICODE_STRING OpenName;
UINT i;
UNICODE_STRING NdsTree;
//
// Copy over the preamble.
//
OpenName.MaximumLength = sizeof( NameStr );
for ( i = 0; i < PreambleLength ; i++ )
NameStr[i] = DevicePreamble[i];
RtlInitUnicodeString( &NdsTree, TreeBuffer );
//
// Copy the server or tree name.
//
for ( i = 0 ; i < ( NdsTree.Length / sizeof( WCHAR ) ) ; i++ ) {
NameStr[i + PreambleLength] = NdsTree.Buffer[i];
}
OpenName.Length = (USHORT)(( i * sizeof( WCHAR ) ) +
( PreambleLength * sizeof( WCHAR ) ));
OpenName.Buffer = NameStr;
//
// Set up the object attributes.
//
InitializeObjectAttributes( &ObjectAttributes,
&OpenName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntstatus = NtOpenFile( &hRdr,
DesiredAccess,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT );
if ( !NT_SUCCESS(ntstatus) )
return ntstatus;
ntstatus = NtFsControlFile( hRdr,
NULL,
NULL,
NULL,
&IoStatusBlock,
FSCTL_NWR_GET_USERNAME,
(PVOID) TreeBuffer,
NdsTree.Length,
(PVOID) UserName,
Length );
UserName[(USHORT)IoStatusBlock.Information/2] = 0;
NtClose( hRdr );
return ntstatus;
}