[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