Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2016-05

Write to UNC or mapped drive

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Leonardo M. Ramé

Hi, My app is a CGI running on Windows2012 (IIS 7.0), it needs to save a file to a remote UNC or Mapped drive, but when I check using DirectoryExists in both cases I get False, but of course the UNC and mapped drive exists.

Any hint?.

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

Reply by email

Denis Kozlov
to Leonardo M. Ramé
Leonardo M. Ram? wrote 5 lines
Hi, My app is a CGI running on Windows2012 (IIS 7.0), it needs to save a file to a remote UNC or Mapped drive, but when I check using DirectoryExists in both cases I get False, but of course the UNC and mapped drive exists.

Does it fail only for the root UNC path but works for a path that contains a folder component?

DirectoryExists internally uses GetFileAttributes WinAPI, which states:

If you call GetFileAttributes for a network share, the function fails, and GetLastError returns ERROR_BAD_NETPATH. You must specify a path to a subfolder on that share.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa364944%28v=vs.85%29.aspx

Denis
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20160525/a833eef8/attachment.html>

Reply by email

Santiago A.
to Leonardo M. Ramé: Hi, My app is a CGI running on Windows2012 (IIS 7.0), it needs to save a file to a remote…

El 24/05/2016 a las 21:46, Leonardo M. Ram? escribi?:

Show quoted text 8 lines
Hi, My app is a CGI running on Windows2012 (IIS 7.0), it needs to save a file to a remote UNC or Mapped drive, but when I check using DirectoryExists in both cases I get False, but of course the UNC and mapped drive exists. Any hint?. Regards,

Not sure 100%, but I think that mapped drives only work when a user opens a desktop session. Services don't know about mapped drives. Think of it, in the same server, different users may map the same network resource with a different letter.

Instead of mapped drives I think you should use \\server\resource, and the user who runs the service that calls the CGI must have permission on that resource. If the service is run as "Local system", I don't know how to grant permission in a remote machine.

Saludos Santiago A. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20160525/ca11f461/attachment.html>

Reply by email

Marc Weustink
to Santiago A.
"Santiago A." wrote 14 lines
El 24/05/2016 a las 21:46, Leonardo M. Ram? escribi?: > Hi, My app is a CGI running on Windows2012 (IIS 7.0), it needs to save > a file to a remote UNC or Mapped drive, but when I check using > DirectoryExists in both cases I get False, but of course the UNC and > mapped drive exists. > > Any hint?. > > Regards, Not sure 100%, but I think that mapped drives only work when a user opens a desktop session. Services don't know about mapped drives. Think of it, in the same server, different users may map the same network resource with a different letter.

Correct. Drivemappings are user specific. You get the same if you want to run something as administrator from a mapping.

Show quoted text 6 lines
Instead of mapped drives I think you should use \\server\resource, and the user who runs the service that calls the CGI must have permission on that resource. If the service is run as "Local system", I don't know how to grant permission in a remote machine.

Depends on windows version, iirc on modern versions local system (or was it local service) it has no network access

Marc

Reply by email

Santiago A.
to Marc Weustink

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. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20160526/947735da/attachment.html>

Reply by email

Leonardo M. Ramé
to Santiago A.

El 26/05/16 a las 08:22, Santiago A. escribi?:

Show quoted text 18 lines
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.

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

Reply by email