diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2005-05-13 20:20:02 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2005-05-13 20:20:02 +0000 |
commit | e01eac68ed93d369c416bbbd16ed1b7d13086462 (patch) | |
tree | a04fc4c14020af223672ebfa01865fdfaf0fe961 | |
parent | 063f1df2aa2689d45fd7fd7bd8445031338ec9cb (diff) | |
download | newlib-e01eac68ed93d369c416bbbd16ed1b7d13086462.zip newlib-e01eac68ed93d369c416bbbd16ed1b7d13086462.tar.gz newlib-e01eac68ed93d369c416bbbd16ed1b7d13086462.tar.bz2 |
* 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.
-rw-r--r-- | winsup/cygwin/ChangeLog | 16 | ||||
-rw-r--r-- | winsup/cygwin/autoload.cc | 4 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_netdrive.cc | 106 |
4 files changed, 125 insertions, 4 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c53384a..2b9e6c2 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2005-05-13 Corinna Vinschen <corinna@vinschen.de> + + * 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 <cgf@timesys.com> Remove PC_FULL from path_conv usage throughout. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index d295940..3d5dd40 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 375866d..be7a6c3 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 0b6aba7..fbb2c16 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 <windows.h> #include "winsup.h" #include <unistd.h> #include <stdlib.h> @@ -20,7 +19,9 @@ details. */ #include "dtable.h" #include "cygheap.h" #include <assert.h> -#include <shlwapi.h> +#include <winnetwk.h> + +#include <dirent.h> /* 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) +{ + 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) { - return NULL; + if (dir->__handle != INVALID_HANDLE_VALUE) + WNetCloseEnum (dir->__handle); + dir->__handle = INVALID_HANDLE_VALUE; + return fhandler_virtual::closedir (dir); } int |