diff options
Diffstat (limited to 'winsup/cygwin/fhandler_netdrive.cc')
-rw-r--r-- | winsup/cygwin/fhandler_netdrive.cc | 338 |
1 files changed, 0 insertions, 338 deletions
diff --git a/winsup/cygwin/fhandler_netdrive.cc b/winsup/cygwin/fhandler_netdrive.cc deleted file mode 100644 index 39ec0cdff..000000000 --- a/winsup/cygwin/fhandler_netdrive.cc +++ /dev/null @@ -1,338 +0,0 @@ -/* fhandler_netdrive.cc: fhandler for // and //MACHINE handling - - Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 - Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include "winsup.h" -#include <stdlib.h> -#include "cygerrno.h" -#include "security.h" -#include "path.h" -#include "fhandler.h" -#include "dtable.h" -#include "cygheap.h" -#include "cygthread.h" -#include "tls_pbuf.h" - -#include <dirent.h> - -enum - { - GET_RESOURCE_OPENENUM = 1, - GET_RESOURCE_OPENENUMTOP = 2, - GET_RESOURCE_ENUM = 3 - }; - -struct netdriveinf - { - int what; - int ret; - PVOID in; - PVOID out; - DWORD outsize; - HANDLE sem; - }; - -struct net_hdls - { - HANDLE net; - HANDLE dom; - }; - -static DWORD WINAPI -thread_netdrive (void *arg) -{ - netdriveinf *ndi = (netdriveinf *) arg; - WCHAR provider[256], *dummy = NULL; - LPNETRESOURCEW nro; - DWORD cnt, size; - struct net_hdls *nh; - tmp_pathbuf tp; - - ReleaseSemaphore (ndi->sem, 1, NULL); - switch (ndi->what) - { - case GET_RESOURCE_OPENENUMTOP: - nro = (LPNETRESOURCEW) tp.c_get (); - nh = (struct net_hdls *) ndi->out; - ndi->ret = WNetGetProviderNameW (WNNC_NET_LANMAN, provider, - (size = 256, &size)); - if (ndi->ret != NO_ERROR) - break; - memset (nro, 0, sizeof *nro); - nro->dwScope = RESOURCE_GLOBALNET; - nro->dwType = RESOURCETYPE_ANY; - nro->dwDisplayType = RESOURCEDISPLAYTYPE_GROUP; - nro->dwUsage = RESOURCEUSAGE_RESERVED | RESOURCEUSAGE_CONTAINER; - nro->lpRemoteName = provider; - nro->lpProvider = provider; - ndi->ret = WNetOpenEnumW (RESOURCE_GLOBALNET, RESOURCETYPE_DISK, - RESOURCEUSAGE_ALL, nro, &nh->net); - if (ndi->ret != NO_ERROR) - break; - while ((ndi->ret = WNetEnumResourceW (nh->net, (cnt = 1, &cnt), nro, - (size = NT_MAX_PATH, &size))) - == NO_ERROR) - { - ndi->ret = WNetOpenEnumW (RESOURCE_GLOBALNET, RESOURCETYPE_DISK, - RESOURCEUSAGE_ALL, nro, &nh->dom); - if (ndi->ret == NO_ERROR) - break; - } - break; - case GET_RESOURCE_OPENENUM: - nro = (LPNETRESOURCEW) tp.c_get (); - nh = (struct net_hdls *) ndi->out; - ndi->ret = WNetGetProviderNameW (WNNC_NET_LANMAN, provider, - (size = 256, &size)); - if (ndi->ret != NO_ERROR) - break; - ((LPNETRESOURCEW) ndi->in)->lpProvider = provider; - ndi->ret = WNetGetResourceInformationW ((LPNETRESOURCEW) ndi->in, nro, - (size = NT_MAX_PATH, &size), - &dummy); - if (ndi->ret != NO_ERROR) - break; - ndi->ret = WNetOpenEnumW (RESOURCE_GLOBALNET, RESOURCETYPE_DISK, - RESOURCEUSAGE_ALL, nro, &nh->dom); - break; - case GET_RESOURCE_ENUM: - nh = (struct net_hdls *) ndi->in; - if (!nh->dom) - { - ndi->ret = ERROR_NO_MORE_ITEMS; - break; - } - nro = (LPNETRESOURCEW) tp.c_get (); - while ((ndi->ret = WNetEnumResourceW (nh->dom, (cnt = 1, &cnt), - (LPNETRESOURCEW) ndi->out, - &ndi->outsize)) != NO_ERROR - && nh->net) - { - WNetCloseEnum (nh->dom); - nh->dom = NULL; - while ((ndi->ret = WNetEnumResourceW (nh->net, (cnt = 1, &cnt), nro, - (size = NT_MAX_PATH, &size))) - == NO_ERROR) - { - ndi->ret = WNetOpenEnumW (RESOURCE_GLOBALNET, RESOURCETYPE_DISK, - RESOURCEUSAGE_ALL, nro, &nh->dom); - if (ndi->ret == NO_ERROR) - break; - } - if (ndi->ret != NO_ERROR) - break; - } - break; - } - ReleaseSemaphore (ndi->sem, 1, NULL); - return 0; -} - -static DWORD -create_thread_and_wait (int what, PVOID in, PVOID out, DWORD outsize, - const char *name) -{ - netdriveinf ndi = { what, 0, in, out, outsize, - CreateSemaphore (&sec_none_nih, 0, 2, NULL) }; - cygthread *thr = new cygthread (thread_netdrive, &ndi, name); - if (thr->detach (ndi.sem)) - ndi.ret = ERROR_OPERATION_ABORTED; - CloseHandle (ndi.sem); - return ndi.ret; -} - -/* 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. */ -virtual_ftype_t -fhandler_netdrive::exists () -{ - char *to; - const char *from; - size_t len = strlen (get_name ()); - if (len == 2) - return virt_rootdir; - - char namebuf[len + 1]; - tmp_pathbuf tp; - PWCHAR name = tp.w_get (); - - for (to = namebuf, from = get_name (); *from; to++, from++) - *to = (*from == '/') ? '\\' : *from; - *to = '\0'; - - struct net_hdls nh = { NULL, NULL }; - NETRESOURCEW nr = {0}; - nr.dwType = RESOURCETYPE_DISK; - sys_mbstowcs (name, NT_MAX_PATH, namebuf); - nr.lpRemoteName = name; - DWORD ret = create_thread_and_wait (GET_RESOURCE_OPENENUM, - &nr, &nh, 0, "WNetOpenEnum"); - if (nh.dom) - WNetCloseEnum (nh.dom); - return ret != NO_ERROR ? virt_none : virt_directory; -} - -fhandler_netdrive::fhandler_netdrive (): - fhandler_virtual () -{ -} - -int __reg2 -fhandler_netdrive::fstat (struct stat *buf) -{ - const char *path = get_name (); - debug_printf ("fstat (%s)", path); - - fhandler_base::fstat (buf); - - buf->st_mode = S_IFDIR | STD_RBITS | STD_XBITS; - buf->st_ino = get_ino (); - - return 0; -} - -int -fhandler_netdrive::readdir (DIR *dir, dirent *de) -{ - NETRESOURCEW *nro; - DWORD ret; - int res; - tmp_pathbuf tp; - - if (!dir->__d_position) - { - size_t len = strlen (get_name ()); - PWCHAR name = NULL; - NETRESOURCEW nr = { 0 }; - struct net_hdls *nh; - - if (len != 2) /* // */ - { - const char *from; - char *to; - char *namebuf = (char *) alloca (len + 1); - for (to = namebuf, from = get_name (); *from; to++, from++) - *to = (*from == '/') ? '\\' : *from; - *to = '\0'; - name = tp.w_get (); - sys_mbstowcs (name, NT_MAX_PATH, namebuf); - } - nr.lpRemoteName = name; - nr.dwType = RESOURCETYPE_DISK; - nh = (struct net_hdls *) ccalloc (HEAP_FHANDLER, 1, sizeof *nh); - ret = create_thread_and_wait (len == 2 ? GET_RESOURCE_OPENENUMTOP - : GET_RESOURCE_OPENENUM, - &nr, nh, 0, "WNetOpenEnum"); - if (ret != NO_ERROR) - { - dir->__handle = INVALID_HANDLE_VALUE; - res = geterrno_from_win_error (ret); - goto out; - } - dir->__handle = (HANDLE) nh; - } - nro = (LPNETRESOURCEW) tp.c_get (); - ret = create_thread_and_wait (GET_RESOURCE_ENUM, dir->__handle, nro, - NT_MAX_PATH, "WnetEnumResource"); - if (ret != NO_ERROR) - res = geterrno_from_win_error (ret); - else - { - dir->__d_position++; - PWCHAR bs = wcsrchr (nro->lpRemoteName, L'\\'); - bs = bs ? bs + 1 : nro->lpRemoteName; - if (strlen (get_name ()) == 2) - { - UNICODE_STRING ss, ds; - - tp.u_get (&ds); - RtlInitUnicodeString (&ss, bs); - RtlDowncaseUnicodeString (&ds, &ss, FALSE); - sys_wcstombs (de->d_name, sizeof de->d_name, - ds.Buffer, ds.Length / sizeof (WCHAR)); - de->d_ino = hash_path_name (get_ino (), de->d_name); - } - else - { - sys_wcstombs (de->d_name, sizeof de->d_name, bs); - char *rpath = tp.c_get (); - sys_wcstombs (rpath, NT_MAX_PATH, nro->lpRemoteName); - de->d_ino = readdir_get_ino (rpath, false); - /* We can't trust remote inode numbers of only 32 bit. That means, - remote NT4 NTFS, as well as shares of Samba version < 3.0. */ - if (de->d_ino <= UINT32_MAX) - de->d_ino = hash_path_name (0, rpath); - } - de->d_type = DT_DIR; - - res = 0; - } -out: - syscall_printf ("%d = readdir(%p, %p)", res, dir, de); - return res; -} - -void -fhandler_netdrive::seekdir (DIR *dir, long pos) -{ - rewinddir (dir); - if (pos < 0) - return; - while (dir->__d_position < pos) - if (readdir (dir, dir->__d_dirent)) - break; -} - -void -fhandler_netdrive::rewinddir (DIR *dir) -{ - if (dir->__handle != INVALID_HANDLE_VALUE) - { - struct net_hdls *nh = (struct net_hdls *) dir->__handle; - if (nh->dom) - WNetCloseEnum (nh->dom); - if (nh->net) - WNetCloseEnum (nh->net); - cfree (nh); - } - dir->__handle = INVALID_HANDLE_VALUE; - return fhandler_virtual::rewinddir (dir); -} - -int -fhandler_netdrive::closedir (DIR *dir) -{ - rewinddir (dir); - return fhandler_virtual::closedir (dir); -} - -int -fhandler_netdrive::open (int flags, mode_t mode) -{ - if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) - { - set_errno (EEXIST); - return 0; - } - if (flags & O_WRONLY) - { - set_errno (EISDIR); - return 0; - } - /* Open a fake handle to \\Device\\Null */ - return open_null (flags); -} - -int -fhandler_netdrive::close () -{ - /* Skip fhandler_virtual::close, which is a no-op. */ - return fhandler_base::close (); -} |