Link to home
Start Free TrialLog in
Avatar of phyderous
phyderous

asked on

Copy file to a network share

Hi,

I need to write a program that save a file to a network share ...

so far it is easy,

The problem is that the logged in user don't have a permission to write to this share

therefore I need the process to logged in into the remote share suppling username and password.

Thanks,

Avi
Avatar of phyderous
phyderous

ASKER

one more thing ... no mapnetworkdrivesolution please

thanks
You may use this

Create a new .bas module and add the following:

Option Explicit
Private Declare Function LogonUser Lib "advapi32.dll" Alias "LogonUserA" (ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal lpszPassword As String, ByVal dwLogonType As Long, ByVal dwLogonProvider As Long, phToken As Long) As Long
Private Declare Function ImpersonateLoggedOnUser Lib "advapi32.dll" (ByVal hToken As Long) As Long
Private Declare Function RevertToSelf Lib "advapi32.dll" () As Long
Private Const LOGON32_PROVIDER_DEFAULT    As Long = 0&
Private Const LOGON32_PROVIDER_WINNT35    As Long = 1&
Private Const LOGON32_LOGON_INTERACTIVE   As Long = 2&
Private Const LOGON32_LOGON_NETWORK       As Long = 3&
Private Const LOGON32_LOGON_BATCH         As Long = 4&
Private Const LOGON32_LOGON_SERVICE       As Long = 5&


Public Function doLogon(ByVal strAdminUser As String, ByVal strAdminPassword As String, ByVal strAdminDomain As String) As Boolean
On Error GoTo DamnErr
    Dim lngTokenHandle As Long
    Dim lngLogonType As Long
    Dim lngLogonProvider As Long
    Dim blnResult As Boolean
    lngLogonType = LOGON32_LOGON_INTERACTIVE
    lngLogonProvider = LOGON32_PROVIDER_DEFAULT
    blnResult = RevertToSelf()
    blnResult = LogonUser(strAdminUser, strAdminDomain, strAdminPassword, _
                                         lngLogonType, lngLogonProvider, _
                                         lngTokenHandle)
    blnResult = ImpersonateLoggedOnUser(lngTokenHandle)
    doLogon = blnResult
    Exit Function
DamnErr:
   Dim sERRORtxt As String
   sERRORtxt = "Error Number: " & Err.Number & vbCrLf & _
               "Description: " & Err.Description & vbCrLf & _
               "Source: " & Err.Source & vbCrLf & _
               "Function: doLogon" & vbCrLf & _
               "Date: " & Now() & vbCrLf & _
               "Input:" & vbCrLf & _
               "  strAdminUser=" & strAdminUser & vbCrLf & _
               "  strAdminPassword=" & strAdminPassword & vbCrLf & _
               "  strAdminDomain=" & strAdminDomain
   App.LogEvent sERRORtxt, vbLogEventTypeError
   Err.Clear
End Function

Public Function doLogoff() As Boolean
On Error GoTo DamnErr
    doLogoff = RevertToSelf()
    Exit Function
DamnErr:
Dim sERRORtxt As String
   sERRORtxt = "Error Number: " & Err.Number & vbCrLf & _
               "Description: " & Err.Description & vbCrLf & _
               "Source: " & Err.Source & vbCrLf & _
               "Function: doLogoff" & vbCrLf & _
               "Date: " & Now()
   App.LogEvent sERRORtxt, vbLogEventTypeError
   Err.Clear
End Function



Call it like:

doLogon "username", "password", "domain-if-needed"
'your code that needs admin rights.
'MAKE SURE TO LOGOFF!
doLogoff
The other alternative is create an activex exe and do the file copying and use dcomcnfg.exe to set to run your exe as admin user.

Call your activex exe from your application
EDDYKT

it is quite amazing ... it seems you are always here :-)

any way the first example if I understand correctly call the logonuser API call which is good for the local computer only ... so it would have been great if it was for a domain ... but it is design to work without a domain as well,

I need it to work without changing client/server computer configuratrion therefore  using dcom ... is no good

I will check the 2 other links you send

and as always thanks a lot
the two links refering to the CreateProcessWithLogon/CreateProcessWithLogonW which is not what I need

I need an explorer like tool

in explorer when you don't have a premission for a spesific resource the "Enter Network password" dialog box is appearing.

I need to do the same with two limitation no dialog box for username password and only my process will have this security attribute

Thanks,

You can do this with a simple batch file(.cmd) if you want. Or you could shell out the commands from a script. Your cmd would look like this. The start wait will make sure that the share has been mapped before it tries to do the copy.

start /wait net use x:\\myserver\myshare /user:domainname\username
copy c:\mypathto\myfile x:\myshare\mycopiedfile



TooKoolKris,

Thanks for your response,

I explicitly ask no networkshare user ...

Thanks
>>any way the first example if I understand correctly call the logonuser API call which is good for the local computer only ... so it would have been great if it was for a domain ... but it is design to work without a domain as well,

>>I need it to work without changing client/server computer configuratrion therefore  using dcom ... is no good

The way you sound is turn off all the alternative. The question here is you won't be able to authenticate the user if the user is only exist on local user.

?-<

>>it is quite amazing ... it seems you are always here :-)


I hope my boss doesn't know. Shhhhh...
The way you sound is turn off all the alternative. The question here is you won't be able to authenticate the user if the user is only exist on local user.


Why not ...

Explorer does it all te time ...

when you enter a path for a remote machine in the address bar and you don't have right to access this machine the "Enter Network Password" Dialog appears you enter username password and you now have access to this machine.

so it must be possiable ... the only question is how ...
Oh sorry didn't realize you were trying to ice skate uphill backwards, my bad, lol.
>>when you enter a path for a remote machine in the address bar and you don't have right to access this machine the "Enter Network Password" Dialog appears you enter username password and you now have access to this machine.


But you have to use KNOWN user name in order to gain an access.

If the user you provided is ONLY in your local account, You won't be able to gain control. Accept you have the same password and username exist on the domain or on that machine you tried to access.

TooKoolKris

:-)

Think of a program that open dos windows in order to copy a single file ...

it is very resanoble request ...
Avatar of Richie_Simonetti
You could use  TooKoolKris's comment regarding batch file and disconnect the share after file was copied.
EDDYKT,

you completele misunderstood me,

I will try to rephrase

I have computers over the network which working in a workgroup

I know the username and password for each of this computers

the current logon user doesn't know this and don;t have the right credantiales to access these computers

I want to create a process that will have access to these computers

from what I see so far using the logonuser function you suggested is only good for the local computer

for example the current user on the computer is "admin1" and I want my thread to have the credantiales of "admin2" then I can use logonuser

When I want to connect to a remote computer I can't use logonuser so I have to use somthing else so I found out that there is a function call LsaLogonUser but the document is quite vouge and coding it in vb from scratch will take me few hours ... so I though if some has some samples it will be great
Richie_Simonetti
there is no reason to use net share and so on ... if I wanted that I would simply used mapnetworkdrivesolution api call

Sector10

either you misunderstood me or I missunderstood the use of lookupaccountname api call

Thanks you all once again
EDDYKT

from the msdn documentation

The LogonUser function attempts to log a user on to the local computer, that is, to the computer from which LogonUser was called. You cannot use LogonUser to log on to a remote computer

Thanks
Thanks all for your posts so far ...

Richie_Simonetti I will check this link

Have a nice weekend

Cheers
"Think of a program that open dos windows in order to copy a single file ...
it is very resanoble request ... "

And just what exactly do you think happens when you create a .cmd file with instructions in it?
TooKoolKris

Where did you see I want to write a .cmd file ?

This is a vb forum therefore pepole here write there own programs ...

and shellexec is not an option.


Hi all,

You can use these two APIs to connect and disconnect from the network shares

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

Public Declare Function WNetCancelConnection2 Lib "mpr.dll" Alias "WNetCancelConnection2A" (ByVal lpName As String, ByVal dwFlags As Long, ByVal fForce As Long) As Long

* if you connect without providing a localname (NULL) it will not map it to a drive letter.

search the MSDN for more information about NetResource & Flags

Regards,
Fahad
Thanks I will check it
Hello to you all.

The WNetUseConnection also makes a connection to a network resource. The main difference is that WNetUseConnection can automatically select an unused local device to redirect to the network resource.

Take look at this example i found:

Create a new Standard EXE project in Visual Basic. Form1 is created by default.
Add three TextBox controls to Form1 and name them txtUNC, txtUser, and txtPWD.
Set the PasswordChar property of txtPWD to an asterisk (*).
Add two CommandButtons to Form1 and set their Captions to CONNECT and DISCONNECT.
Paste the following code into the code window of Form1:Option Explicit

' CONSTANTS
Private Const NO_ERROR = 0
Private Const CONNECT_LOCALDRIVE = 256
Private Const CONNECT_REDIRECT = 128
Private Const RESOURCE_GLOBALNET = &H2
Private Const RESOURCETYPE_DISK = &H1
Private Const RESOURCEDISPLAYTYPE_SHARE = &H3
Private Const RESOURCEUSAGE_CONNECTABLE = &H1
Private Const CONNECT_UPDATE_PROFILE = 1

' LOCAL VARIABLES
Private MappedDrive As String

' CUSTOM TYPES
Private Type NETRESOURCE
    dwScope As Long
    dwType As Long
    dwDisplayType As Long
    dwUsage As Long
    lpLocalName As String
    lpRemoteName As String
    lpComment As String
    lpProvider As String
End Type

' API DECLARATIONS
Private Declare Function WNetUseConnection Lib "mpr.dll" _
   Alias "WNetUseConnectionA" ( _
   ByVal hwndOwner As Long, _
   ByRef lpNetResource As NETRESOURCE, _
   ByVal lpUsername As String, _
   ByVal lpPassword As String, _
   ByVal dwFlags As Long, _
   ByVal lpAccessName As Any, _
   ByRef lpBufferSize As Long, _
   ByRef lpResult As Long) _
   As Long

Private Declare Function WNetCancelConnection2 Lib "mpr.dll" _
   Alias "WNetCancelConnection2A" ( _
   ByVal lpName As String, _
   ByVal dwFlags As Long, _
   ByVal fForce As Long) _
   As Long

Private Sub Command1_Click()
   Dim NetR As NETRESOURCE    ' NetResouce structure
   Dim ErrInfo As Long        ' Return value from API
   Dim buffer As String       ' Drive letter assigned to resource
   Dim bufferlen As Long      ' Size of the buffer
   Dim success As Long        ' Additional info about API call
   
   ' Initialize the NetResouce structure
   NetR.dwScope = RESOURCE_GLOBALNET
   NetR.dwType = RESOURCETYPE_DISK
   NetR.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE
   NetR.dwUsage = RESOURCEUSAGE_CONNECTABLE
   NetR.lpLocalName = vbNullString
   NetR.lpRemoteName = txtUNC.Text

   ' Initialize the return buffer and buffer size
   buffer = Space(32)
   bufferlen = Len(buffer)

   ' Call API to map the drive
   ErrInfo = WNetUseConnection(Me.hWnd, NetR, txtPWD.Text, txtUser.Text, _
      CONNECT_REDIRECT, buffer, bufferlen, success)

   ' Check if call to API failed. According to the MSDN help, there
   ' are some versions of the operating system that expect the userid
   ' as the 3rd parameter and the password as the 4th, while other
   ' versions of the operating system have them in reverse order, so
   ' if first call to API fails, try reversing these two parameters.
   If ErrInfo <> NO_ERROR Then
      ' Call API with userid and password switched
      ErrInfo = WNetUseConnection(Me.hWnd, NetR, txtUser.Text, _
         txtPWD.Text, CONNECT_REDIRECT, buffer, bufferlen, success)
   End If

   ' Check for success
   If (ErrInfo = NO_ERROR) And (success = CONNECT_LOCALDRIVE) Then
      ' Store the mapped drive letter for later usage
      MappedDrive = Left$(buffer, InStr(1, buffer, ":"))

      ' Display the mapped drive letter
      MsgBox "Connect Succeeded to " & MappedDrive
   Else
      MsgBox "ERROR: " & Str(ErrInfo) & " - Connect Failed!"
   End If
End Sub

Private Sub Command2_Click()
   Dim ErrInfo As Long     ' Return value from API

   ' Call API to disconnect the drive
   ErrInfo = WNetCancelConnection2(MappedDrive, _
      CONNECT_UPDATE_PROFILE, False)

   ' Check for success
   If ErrInfo = NO_ERROR Then
      MsgBox "Disconnect of '" & MappedDrive & "' Succeeded"
     
      ' Clear the mapped drive letter
      MappedDrive = ""
   Else
      MsgBox "ERROR: " & Str(ErrInfo) & " - Disconnect Failed!"
   End If
End Sub

Save and run the sample.
In the first TextBox, type the UNC path to the share you wish to map to a drive letter (such as, \\ServerName\ShareName).
In the second TextBox, type your network logon name.
In the third TextBox, type your password.
Click the CONNECT button.

RESULT: Provided you have typed a valid user id, password, network share, and have the appropriate network permissions, you should receive a message indicating that the share was connected and the mapped drive letter is given. You can verify the map by opening the Windows Explorer.
Click the DISCONNECT button.

RESULT: The mapped drive is disconnected. Again, this can be verified with the Windows Explorer.


Regards,

Paul
ASKER CERTIFIED SOLUTION
Avatar of PashaMod
PashaMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial