diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c53384ab5..2b9e6c23c 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2005-05-13 Corinna Vinschen + + * autoload.cc (WNetGetResourceParentA): Import. + (WNetOpenEnumA): Import. + (WNetEnumResourceA): Import. + (WNetCloseEnum): Import. + * fhandler.h (fhandler_netdrive::telldir): Add declaration. + (fhandler_netdrive::seekdir): Ditto. + (fhandler_netdrive::closedir): Ditto. + * fhandler_netdrive.cc: Drop explicit including windows.h. Include + winnetwk.h instead of shlwapi.h. Include dirent.h. + (fhandler_netdrive::readdir): Implement. + (fhandler_netdrive::telldir): New method. + (fhandler_netdrive::seekdir): New method. + (fhandler_netdrive::closedir): Ditto. + 2005-05-13 Christopher Faylor Remove PC_FULL from path_conv usage throughout. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index d2959402d..3d5dd4086 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -558,6 +558,10 @@ LoadDLLfuncEx (waveInReset, 4, winmm, 1) LoadDLLfuncEx (waveInClose, 4, winmm, 1) LoadDLLfunc (WNetGetResourceInformationA, 16, mpr) +LoadDLLfunc (WNetGetResourceParentA, 12, mpr) +LoadDLLfunc (WNetOpenEnumA, 20, mpr) +LoadDLLfunc (WNetEnumResourceA, 16, mpr) +LoadDLLfunc (WNetCloseEnum, 4, mpr) LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1) LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 375866d54..be7a6c38b 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1220,6 +1220,9 @@ class fhandler_netdrive: public fhandler_virtual fhandler_netdrive (); int exists(); struct dirent *readdir (DIR *); + _off64_t telldir (DIR *); + void seekdir (DIR *, _off64_t); + int closedir (DIR *); int open (int flags, mode_t mode = 0); int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2))); }; diff --git a/winsup/cygwin/fhandler_netdrive.cc b/winsup/cygwin/fhandler_netdrive.cc index 0b6aba7d3..fbb2c1689 100644 --- a/winsup/cygwin/fhandler_netdrive.cc +++ b/winsup/cygwin/fhandler_netdrive.cc @@ -8,7 +8,6 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#include #include "winsup.h" #include #include @@ -20,7 +19,9 @@ details. */ #include "dtable.h" #include "cygheap.h" #include -#include +#include + +#include /* Returns 0 if path doesn't exist, >0 if path is a directory, -1 if path is a file, -2 if it's a symlink. */ @@ -70,9 +71,106 @@ fhandler_netdrive::fstat (struct __stat64 *buf) } struct dirent * -fhandler_netdrive::readdir (DIR * dir) +fhandler_netdrive::readdir (DIR *dir) { - return NULL; + DWORD size; + NETRESOURCE *nro; + DWORD ret; + + if (!dir->__d_position) + { + size_t len = strlen (get_name ()); + char *namebuf, *dummy; + NETRESOURCE nr = { 0 }, *nro2; + + if (len == 2) /* // */ + { + namebuf = (char *) alloca (MAX_COMPUTERNAME_LENGTH + 3); + strcpy (namebuf, "\\\\"); + size = MAX_COMPUTERNAME_LENGTH + 1; + if (!GetComputerName (namebuf + 2, &size)) + { + __seterrno (); + return NULL; + } + } + else + { + const char *from; + char *to; + namebuf = (char *) alloca (len + 1); + for (to = namebuf, from = get_name (); *from; to++, from++) + *to = (*from == '/') ? '\\' : *from; + *to = '\0'; + } + + nr.lpRemoteName = namebuf; + nr.dwType = RESOURCETYPE_DISK; + size = 4096; + nro = (NETRESOURCE *) alloca (size); + ret = WNetGetResourceInformation (&nr, nro, &size, &dummy); + if (ret != NO_ERROR) + { + __seterrno (); + return NULL; + } + + if (len == 2) + { + nro2 = nro; + size = 4096; + nro = (NETRESOURCE *) alloca (size); + ret = WNetGetResourceParent (nro2, nro, &size); + if (ret != NO_ERROR) + { + __seterrno (); + return NULL; + } + } + ret = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, + nro, &dir->__handle); + if (ret != NO_ERROR) + { + __seterrno (); + dir->__handle = INVALID_HANDLE_VALUE; + return NULL; + } + } + /* FIXME: dot and dot_dot handling */ + DWORD cnt = 1; + size = 16384; /* As documented in MSDN. */ + nro = (NETRESOURCE *) alloca (size); + ret = WNetEnumResource (dir->__handle, &cnt, nro, &size); + if (ret != NO_ERROR) + { + if (ret != ERROR_NO_MORE_ITEMS) + __seterrno (); + return NULL; + } + dir->__d_position++; + char *bs = strrchr (nro->lpRemoteName, '\\'); + strcpy (dir->__d_dirent->d_name, bs ? bs + 1 : nro->lpRemoteName); + return dir->__d_dirent; +} + +_off64_t +fhandler_netdrive::telldir (DIR *dir) +{ + return -1; +} + +void +fhandler_netdrive::seekdir (DIR *, _off64_t) +{ +} + +int +fhandler_netdrive::closedir (DIR *dir) +{ + if (dir->__handle != INVALID_HANDLE_VALUE) + WNetCloseEnum (dir->__handle); + dir->__handle = INVALID_HANDLE_VALUE; + return fhandler_virtual::closedir (dir); } int