martes, septiembre 14, 2010

Mapeos de unidades de red de otros dominios

Hola,

Hoy he tenido que hacer un tema en el trabajo que puede que os sea útil alguna vez.

Se trata de hacer un formulario .net en el que el usuario tiene que meter el código de usuario y la password de un dominio Windows.

El programita lo que tiene que hacer es el mapeo.

Para hacer esto hay que tirar de la API de Windows porque en el framework .NET (al menos en el del Visual Studio .NET 2005 que es el framework 2.0) que utilizamos no tengo una clase para ello.

Importante: La alternativa que parece fácil, es utilizar el comando "net use" del sistema operativo para hacer el mapeo. Yo lo hice así al principio, pero cuando hay varios mapeos produce problemas. Un proceso net se pega con otro y los mapeos al final fallan mucho.

Así que empezaremos declarando la función WNetAddConnection2:

De esta forma ya podemos preparar la función que hace el mapeo:


Antes de mapear las unidades es mejor desmapearlas. Así que preparamos la función de desmapeo:


El código fuente va más abajo (cuidado porque igual Blogger lo deteriora un poco).

Lo importante son estos detalles:

1.-Al acceder a otro dominio en lugar del usuario a secas hay que pasarle a la función WNetAddConnection2 la pareja formada por dominio\usuario (hay una contrabarra entre los dos, pero igual blogger lo quita).

2.-A lpLocalName hay que pasarle la letra de la unidad a mapear seguido de dos puntos. Por ejemplo M:

3.-Cuidado con el orden de los parámetros. A WNetAddConnection2 hay que pasarle primero la password y luego el usuario.

4.-Hay que controlar los errores 85 (unidad ya mapeada) y 1326 (usuario o password incorrecto).

Public Class Form1

Public Declare Function WNetAddConnection2 Lib "mpr.dll" Alias "WNetAddConnection2A" _
(ByRef lpNetResource As NETRESOURCE, ByVal lpPassword As String, _
ByVal lpUserName As String, ByVal dwFlags As Integer) As Integer

Public Declare Function WNetCancelConnection2 Lib "mpr" Alias "WNetCancelConnection2A" _
(ByVal lpName As String, ByVal dwFlags As Integer, ByVal fForce As Integer) As Integer

Public Structure NETRESOURCE
Public dwScope As Integer
Public dwType As Integer
Public dwDisplayType As Integer
Public dwUsage As Integer
Public lpLocalName As String
Public lpRemoteName As String
Public lpComment As String
Public lpProvider As String
End Structure

Public Const ForceDisconnect As Integer = 1
Public Const RESOURCETYPE_DISK As Long = &H1

Public Function MapDrive(ByVal DriveLetter As String, ByVal UNCPath As String) As Boolean

Dim nr As NETRESOURCE
Dim strUsername As String
Dim strPassword As String

nr = New NETRESOURCE
nr.lpRemoteName = UNCPath
nr.lpLocalName = DriveLetter & ":"
strUsername = "xxxxxxxxxxx\" & Me.txtErabiltzailea.Text
strPassword = Me.txtPasahitza.Text
nr.dwType = RESOURCETYPE_DISK

Dim result As Integer
result = WNetAddConnection2(nr, strPassword, strUsername, 0)

If result = 0 Then
Return True
Else
If result = 85 Then
'El resultado 85 se da cuando la unidad ya está mapeada.
'en ese caso salimos de esta función.
Exit Function
Else
If result = 1326 Then
MsgBox("Usuario o Password incorrecto")
Else
MsgBox("Se ha producido un error")
End If
End If
Me.Close() 'Cierra el formulario actual.
Return False
End If
End Function

Public Function UnMapDrive(ByVal DriveLetter As String) As Boolean
Dim rc As Integer
rc = WNetCancelConnection2(DriveLetter & ":", 0, ForceDisconnect)

If rc = 0 Then
Return True
Else
Return False
End If

End Function



Saludos.

No hay comentarios: