[Lazarus] Write to UNC or mapped drive

Leonardo M. Ramé l.rame at griensu.com
Thu May 26 17:53:02 CEST 2016



El 26/05/16 a las 08:22, Santiago A. escribió:
> El 25/05/2016 a las 21:48, Marc Weustink escribió:
>> Correct. Drivemappings are user specific. You get the same if you want
>> to run something as administrator from a mapping.
> More than user specific are desktop session specific.
>
>> Depends on windows version, iirc on modern versions local system (or was it local service) it has no network access
>> Marc
>
> I think there is a user named "NetworkService", that at least has access
> to network. Obviously, it has to open the session on the remote resource.
>
> --
> Saluds
>
> Santiago A.
> svaa at ciberpiula.net
>
>

Thanks to all. The solution was to impersonate the user, then create the 
mapped drive by code (using the NetUseAdd function, see below), write 
the files to the destination drive, then NetUseDelete:

function Impersonate(const User, PW: string): Boolean;
var
   LogonType         : Integer;
   LogonProvider     : Integer;
   TokenHandle       : THandle;
   strAdminUser      : string;
   strAdminDomain    : string;
   strAdminPassword  : string;
begin
   LogonType := LOGON32_LOGON_INTERACTIVE;
   LogonProvider := LOGON32_PROVIDER_DEFAULT;
   strAdminUser := USER;
   strAdminDomain := '';
   strAdminPassword := PW;
   Result := LogonUser(PChar(strAdminUser), nil,
     PChar(strAdminPassword), LogonType, LogonProvider, TokenHandle);
   if Result then
   begin
     Result := ImpersonateLoggedOnUser(TokenHandle);
   end;
end;

function NetUseAdd(const LocalName, RemoteName, UserName, Password: 
string; var AccessName: string): DWord;
var
   netResource: TNetResource;
   dwResult, dwBufSize, dwFlags: DWORD;
   hRes: DWORD;
   buf: array[0..1024] of Char;
begin
   dwFlags := CONNECT_REDIRECT;
   ZeroMemory(@netResource, sizeof(TNetResource));
   with netResource do begin
     dwType := RESOURCETYPE_DISK;
     lpLocalName := PAnsiChar(LocalName);
     lpRemoteName := PAnsiChar(RemoteName);
     lpProvider := nil;
   end;
   dwBufSize := Sizeof(buf);
   result := WNetUseConnection(0, netResource, PAnsiChar(Password), 
PAnsiChar(UserName), dwFlags, buf, dwBufSize, dwResult);
   if hRes = NO_ERROR then
     AccessName := buf;
end;

function NetUseDelete(const LocalName: string): Boolean;
var
   hRes: DWORD;
begin
   hRes := WNetCancelConnection2(PChar(LocalName), 
CONNECT_UPDATE_PROFILE, true);
   result := (hres = NO_ERROR);
end;

To use these:

var
   lAccess: string;

begin
   if Impersonate('user', 'pass') then
   begin
     NetUseAdd('X:', '\\server\directory', 'remoteuser', 'remotepass', 
lAccess);
     // write files to X:\
     NetUseDelete('X:');
   end;
end;


Regards,
-- 
Leonardo M. Ramé
Medical IT - Griensu S.A.
Av. Colón 636 - Piso 8 Of. A
X5000EPT -- Córdoba
Tel.: +54(351)4246924 +54(351)4247788 +54(351)4247979 int. 19
Cel.: +54 9 (011) 40871877




More information about the Lazarus mailing list