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

375 lines
8.4 KiB
C

/*++
Copyright (C) 1993 Microsoft Corporation
Module Name:
NWATTACH.C
Abstract:
This module contains the NetWare(R) SDK support to routines
into the NetWare redirector
Author:
Chris Sandys (a-chrisa) 09-Sep-1993
Revision History:
Chuck Y. Chan (chuckc) 02/06/94 Moved to NWCS. Make it more NT like.
Chuck Y. Chan (chuckc) 02/27/94 Clear out old code.
Make logout work.
Check for error in many places.
Dont hard code strings.
Remove non compatible parameters.
Lotsa other cleanup.
Felix Wong (t-felixw) 09/16/96 Moved functions for Win95 port.
--*/
#include "procs.h"
#include "nwapi32.h"
#include <stdio.h>
//
// Define structure for internal use. Our handle passed back from attach to
// file server will be pointer to this. We keep server string around for
// discnnecting from the server on logout. The structure is freed on detach.
// Callers should not use this structure but treat pointer as opaque handle.
//
typedef struct _NWC_SERVER_INFO {
HANDLE hConn ;
UNICODE_STRING ServerString ;
} NWC_SERVER_INFO, *PNWC_SERVER_INFO ;
//
// define define categories of errors
//
typedef enum _NCP_CLASS {
NcpClassConnect,
NcpClassBindery,
NcpClassDir
} NCP_CLASS ;
//
// define error mapping structure
//
typedef struct _NTSTATUS_TO_NCP {
NTSTATUS NtStatus ;
NWCCODE NcpCode ;
} NTSTATUS_TO_NCP, *LPNTSTATUS_TO_NCP ;
NWCCODE
MapNtStatus(
const NTSTATUS ntstatus,
const NCP_CLASS ncpclass
);
DWORD
SetWin32ErrorFromNtStatus(
NTSTATUS NtStatus
) ;
DWORD
szToWide(
LPWSTR lpszW,
LPCSTR lpszC,
INT nSize
);
//
// Forwards
//
NTSTATUS
NwAttachToServer(
LPWSTR ServerName,
LPHANDLE phandleServer
);
NTSTATUS
NwDetachFromServer(
HANDLE handleServer
);
NWCCODE NWAPI DLLEXPORT
NWAttachToFileServer(
const char NWFAR *pszServerName,
NWLOCAL_SCOPE ScopeFlag,
NWCONN_HANDLE NWFAR *phNewConn
)
{
DWORD dwRes;
NWCCODE nwRes;
LPWSTR lpwszServerName; // Pointer to buffer for WIDE servername
int nSize;
PNWC_SERVER_INFO pServerInfo ;
//
// check parameters and init return result to be null.
//
if (!pszServerName || !phNewConn)
return INVALID_CONNECTION ;
*phNewConn = NULL ;
//
// Allocate a buffer for wide server name
//
nSize = strlen(pszServerName)+1 ;
if(!(lpwszServerName = (LPWSTR) LocalAlloc(
LPTR,
nSize * sizeof(WCHAR) )))
{
nwRes = REQUESTER_ERROR ;
goto ExitPoint ;
}
if (szToWide( lpwszServerName, pszServerName, nSize ) != NO_ERROR)
{
nwRes = REQUESTER_ERROR ;
goto ExitPoint ;
}
//
// Call createfile to get a handle for the redirector calls
//
nwRes = NWAttachToFileServerW( lpwszServerName,
ScopeFlag,
phNewConn );
ExitPoint:
//
// Free the memory allocated above before exiting
//
if (lpwszServerName)
(void) LocalFree( (HLOCAL) lpwszServerName );
//
// Return with NWCCODE
//
return( nwRes );
}
NWCCODE NWAPI DLLEXPORT
NWAttachToFileServerW(
const WCHAR NWFAR *pszServerName,
NWLOCAL_SCOPE ScopeFlag,
NWCONN_HANDLE NWFAR *phNewConn
)
{
DWORD NtStatus;
NWCCODE nwRes;
LPWSTR lpwszServerName; // Pointer to buffer for WIDE servername
int nSize;
PNWC_SERVER_INFO pServerInfo = NULL;
UNREFERENCED_PARAMETER(ScopeFlag) ;
//
// check parameters and init return result to be null.
//
if (!pszServerName || !phNewConn)
return INVALID_CONNECTION ;
*phNewConn = NULL ;
//
// Allocate a buffer to store the file server name
//
nSize = wcslen(pszServerName)+3 ;
if(!(lpwszServerName = (LPWSTR) LocalAlloc(
LPTR,
nSize * sizeof(WCHAR) )))
{
nwRes = REQUESTER_ERROR ;
goto ExitPoint ;
}
wcscpy( lpwszServerName, L"\\\\" );
wcscat( lpwszServerName, pszServerName );
//
// Allocate a buffer for the server info (handle + name pointer). Also
// init the unicode string.
//
if( !(pServerInfo = (PNWC_SERVER_INFO) LocalAlloc(
LPTR,
sizeof(NWC_SERVER_INFO))) )
{
nwRes = REQUESTER_ERROR ;
goto ExitPoint ;
}
RtlInitUnicodeString(&pServerInfo->ServerString, lpwszServerName) ;
//
// Call createfile to get a handle for the redirector calls
//
NtStatus = NwAttachToServer( lpwszServerName, &pServerInfo->hConn );
if(NT_SUCCESS(NtStatus))
{
nwRes = SUCCESSFUL;
}
else
{
(void) SetWin32ErrorFromNtStatus( NtStatus );
nwRes = MapNtStatus( NtStatus, NcpClassConnect );
}
ExitPoint:
//
// Free the memory allocated above before exiting
//
if (nwRes != SUCCESSFUL)
{
if (lpwszServerName)
(void) LocalFree( (HLOCAL) lpwszServerName );
if (pServerInfo)
(void) LocalFree( (HLOCAL) pServerInfo );
}
else
*phNewConn = (HANDLE) pServerInfo ;
//
// Return with NWCCODE
//
return( nwRes );
}
NWCCODE NWAPI DLLEXPORT
NWDetachFromFileServer(
NWCONN_HANDLE hConn
)
{
PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
(void) NwDetachFromServer( pServerInfo->hConn );
(void) LocalFree (pServerInfo->ServerString.Buffer) ;
//
// catch any body that still trirs to use this puppy...
//
pServerInfo->ServerString.Buffer = NULL ;
pServerInfo->hConn = NULL ;
(void) LocalFree (pServerInfo) ;
return SUCCESSFUL;
}
//
// worker routines
//
#define NW_RDR_SERVER_PREFIX L"\\Device\\Nwrdr\\"
NTSTATUS
NwAttachToServer(
IN LPWSTR ServerName,
OUT LPHANDLE phandleServer
)
/*++
Routine Description:
This routine opens a handle to the given server.
Arguments:
ServerName - The server name to attach to.
phandleServer - Receives an opened handle to the preferred or
nearest server.
Return Value:
0 or reason for failure.
--*/
{
NTSTATUS ntstatus = STATUS_SUCCESS;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
LPWSTR FullName;
UNICODE_STRING UServerName;
FullName = (LPWSTR) LocalAlloc( LMEM_ZEROINIT,
(UINT) ( wcslen( NW_RDR_SERVER_PREFIX) +
wcslen( ServerName ) - 1) *
sizeof(WCHAR)
);
if ( FullName == NULL ) {
return STATUS_INSUFFICIENT_RESOURCES ;
}
wcscpy( FullName, NW_RDR_SERVER_PREFIX );
wcscat( FullName, ServerName + 2 ); // Skip past the prefix "\\"
RtlInitUnicodeString( &UServerName, FullName );
InitializeObjectAttributes(
&ObjectAttributes,
&UServerName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
//
// Open a handle to the preferred server.
//
ntstatus = NtOpenFile(
phandleServer,
SYNCHRONIZE | FILE_LIST_DIRECTORY,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT
);
if ( NT_SUCCESS(ntstatus)) {
ntstatus = IoStatusBlock.Status;
}
if (! NT_SUCCESS(ntstatus)) {
*phandleServer = NULL;
}
LocalFree( FullName );
return (ntstatus);
}
NTSTATUS
NwDetachFromServer(
IN HANDLE handleServer
)
/*++
Routine Description:
This routine closes a handle to the given server.
Arguments:
handleServer - Supplies a open handle to be closed.
Return Value:
NO_ERROR or reason for failure.
--*/
{
NTSTATUS ntstatus = NtClose( handleServer );
return (ntstatus);
};