375 lines
8.4 KiB
C
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);
|
|
};
|
|
|