From e3e7dd3331b5c6980a9e0e059cfa10b5e2cefcaf Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Tue, 2 Aug 2016 10:10:25 +0000 Subject: [PATCH] [NET] Implement the "net use" usage of the net command. This allows connecting remote resources to local system with assigning them a local name, to enumerate such connected resources and to delete them. This obsoletes the hackssign application. The implementation is a bit... raw. It is mainly here to demonstrate what's doable in ReactOS now. And to help using features we were lacking up to now. For instance, you can make use of 'net use * \\vmware-host\Shared Folders\{YOURSHARE}' to assign a local letter to your VMware shared folders. ROSAPPS-303 svn path=/trunk/; revision=72088 --- .../applications/network/net/CMakeLists.txt | 3 +- .../base/applications/network/net/cmdUse.c | 191 ++++++++++++++++++ reactos/base/applications/network/net/main.c | 2 +- reactos/base/applications/network/net/net.h | 2 + 4 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 reactos/base/applications/network/net/cmdUse.c diff --git a/reactos/base/applications/network/net/CMakeLists.txt b/reactos/base/applications/network/net/CMakeLists.txt index 5ae08e7a185..a3170dec12e 100644 --- a/reactos/base/applications/network/net/CMakeLists.txt +++ b/reactos/base/applications/network/net/CMakeLists.txt @@ -10,12 +10,13 @@ list(APPEND SOURCE cmdPause.c cmdStart.c cmdStop.c + cmdUse.c cmdUser.c help.c net.h) add_executable(net ${SOURCE} net.rc) set_module_type(net win32cui UNICODE) -add_importlibs(net advapi32 netapi32 msvcrt kernel32 user32 ntdll) +add_importlibs(net advapi32 netapi32 msvcrt kernel32 user32 ntdll mpr) add_pch(net net.h SOURCE) add_cd_file(TARGET net DESTINATION reactos/system32 FOR all) diff --git a/reactos/base/applications/network/net/cmdUse.c b/reactos/base/applications/network/net/cmdUse.c new file mode 100644 index 00000000000..b04583c6630 --- /dev/null +++ b/reactos/base/applications/network/net/cmdUse.c @@ -0,0 +1,191 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS net command + * FILE: base/applications/network/net/cmdUse.c + * PURPOSE: + * + * PROGRAMMERS: Pierre Schweitzer + */ + +#include "net.h" + +static +DWORD +EnumerateConnections(LPCWSTR Local) +{ + DWORD dRet; + HANDLE hEnum; + LPNETRESOURCE lpRes; + DWORD dSize = 0x1000; + DWORD dCount = -1; + LPNETRESOURCE lpCur; + + printf("%S\t\t\t%S\t\t\t\t%S\n", L"Local", L"Remote", L"Provider"); + + dRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, 0, NULL, &hEnum); + if (dRet != WN_SUCCESS) + { + return 1; + } + + lpRes = HeapAlloc(GetProcessHeap(), 0, dSize); + if (!lpRes) + { + WNetCloseEnum(hEnum); + return 1; + } + + do + { + dSize = 0x1000; + dCount = -1; + + memset(lpRes, 0, dSize); + dRet = WNetEnumResource(hEnum, &dCount, lpRes, &dSize); + if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA) + { + lpCur = lpRes; + for (; dCount; dCount--) + { + if (!Local || wcsicmp(lpCur->lpLocalName, Local) == 0) + { + printf("%S\t\t\t%S\t\t%S\n", lpCur->lpLocalName, lpCur->lpRemoteName, lpCur->lpProvider); + } + + lpCur++; + } + } + } while (dRet != WN_NO_MORE_ENTRIES); + + HeapFree(GetProcessHeap(), 0, lpRes); + WNetCloseEnum(hEnum); + + return 0; +} + +INT +cmdUse( + INT argc, + WCHAR **argv) +{ + DWORD Status, Len; + + if (argc == 2) + { + Status = EnumerateConnections(NULL); + printf("Status: %lu\n", Status); + return 0; + } + else if (argc == 3) + { + Len = wcslen(argv[2]); + if (Len != 2) + { + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName"); + return 1; + } + + if (!iswalpha(argv[2][0]) || argv[2][1] != L':') + { + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName"); + return 1; + } + + Status = EnumerateConnections(argv[2]); + printf("Status: %lu\n", Status); + return 0; + } + + Len = wcslen(argv[2]); + if (Len != 1 && Len != 2) + { + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName"); + printf("Len: %lu\n", Len); + return 1; + } + + if (Len == 2 && argv[2][1] != L':') + { + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName"); + return 1; + } + + if (argv[2][0] != L'*' && !iswalpha(argv[2][0])) + { + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName"); + return 1; + } + + if (wcsicmp(argv[3], L"/DELETE") == 0) + { + if (argv[2][0] == L'*') + { + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName"); + return 1; + } + + return WNetCancelConnection(argv[2], FALSE); + } + else + { + BOOL Persist = FALSE; + NETRESOURCE lpNet; + + Len = wcslen(argv[3]); + if (Len < 4) + { + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"Name"); + return 1; + } + + if (argv[3][0] != L'\\' || argv[3][1] != L'\\') + { + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"Name"); + return 1; + } + + if (argc > 4) + { + LPWSTR Cpy; + Len = wcslen(argv[4]); + if (Len > 12) + { + Cpy = HeapAlloc(GetProcessHeap(), 0, (Len + 1) * sizeof(WCHAR)); + if (Cpy) + { + INT i; + for (i = 0; i < Len; ++i) + Cpy[i] = towupper(argv[4][i]); + + if (wcsstr(Cpy, L"/PERSISTENT:") == Cpy) + { + LPWSTR Arg = Cpy + 12; + if (Len == 14 && Arg[0] == 'N' && Arg[1] == 'O') + { + Persist = FALSE; + } + else if (Len == 15 && Arg[0] == 'Y' && Arg[1] == 'E' && Arg[2] == 'S') + { + Persist = TRUE; + } + else + { + HeapFree(GetProcessHeap(), 0, Cpy); + PrintResourceString(IDS_ERROR_INVALID_OPTION_VALUE, L"Persistent"); + return 1; + } + } + HeapFree(GetProcessHeap(), 0, Cpy); + } + } + + } + + lpNet.dwType = RESOURCETYPE_DISK; + lpNet.lpLocalName = (argv[2][0] != L'*') ? argv[2] : NULL; + lpNet.lpRemoteName = argv[3]; + lpNet.lpProvider = NULL; + + return WNetAddConnection2(&lpNet, NULL, NULL, CONNECT_REDIRECT | (Persist ? CONNECT_UPDATE_PROFILE : 0)); + } +} diff --git a/reactos/base/applications/network/net/main.c b/reactos/base/applications/network/net/main.c index 36df766c2bd..a5b8f94f348 100644 --- a/reactos/base/applications/network/net/main.c +++ b/reactos/base/applications/network/net/main.c @@ -39,7 +39,7 @@ COMMAND cmds[] = {L"statistics", unimplemented}, {L"stop", cmdStop}, {L"time", unimplemented}, - {L"use", unimplemented}, + {L"use", cmdUse}, {L"user", cmdUser}, {L"view", unimplemented}, {NULL, NULL} diff --git a/reactos/base/applications/network/net/net.h b/reactos/base/applications/network/net/net.h index f117f31ca02..65d8777f94f 100644 --- a/reactos/base/applications/network/net/net.h +++ b/reactos/base/applications/network/net/net.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,7 @@ INT cmdLocalGroup(INT argc, WCHAR **argv); INT cmdPause(INT argc, WCHAR **argv); INT cmdStart(INT argc, WCHAR **argv); INT cmdStop(INT argc, WCHAR **argv); +INT cmdUse(INT argc, WCHAR **argv); INT cmdUser(INT argc, WCHAR **argv); #endif /* _NET_PCH_ */ -- 2.17.1