xref: /reactos/base/applications/network/net/cmdUse.c (revision d6eebaa4)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS net command
4  * FILE:            base/applications/network/net/cmdUse.c
5  * PURPOSE:
6  *
7  * PROGRAMMERS:     Pierre Schweitzer
8  */
9 
10 #include "net.h"
11 
12 static
13 DWORD
14 EnumerateConnections(LPCWSTR Local)
15 {
16     DWORD dRet;
17     HANDLE hEnum;
18     LPNETRESOURCE lpRes;
19     DWORD dSize = 0x1000;
20     DWORD dCount = -1;
21     LPNETRESOURCE lpCur;
22 
23     ConPrintf(StdOut, L"%s\t\t\t%s\t\t\t\t%s\n", L"Local", L"Remote", L"Provider");
24 
25     dRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, 0, NULL, &hEnum);
26     if (dRet != WN_SUCCESS)
27     {
28         return 1;
29     }
30 
31     lpRes = HeapAlloc(GetProcessHeap(), 0, dSize);
32     if (!lpRes)
33     {
34         WNetCloseEnum(hEnum);
35         return 1;
36     }
37 
38     do
39     {
40         dSize = 0x1000;
41         dCount = -1;
42 
43         memset(lpRes, 0, dSize);
44         dRet = WNetEnumResource(hEnum, &dCount, lpRes, &dSize);
45         if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
46         {
47             lpCur = lpRes;
48             for (; dCount; dCount--)
49             {
50                 if (!Local || _wcsicmp(lpCur->lpLocalName, Local) == 0)
51                 {
52                     ConPrintf(StdOut, L"%s\t\t\t%s\t\t%s\n", lpCur->lpLocalName, lpCur->lpRemoteName, lpCur->lpProvider);
53                 }
54 
55                 lpCur++;
56             }
57         }
58     } while (dRet != WN_NO_MORE_ENTRIES);
59 
60     HeapFree(GetProcessHeap(), 0, lpRes);
61     WNetCloseEnum(hEnum);
62 
63     return 0;
64 }
65 
66 static
67 VOID
68 PrintError(DWORD Status)
69 {
70     WCHAR szStatusBuffer[16];
71     LPWSTR Buffer;
72 
73     swprintf(szStatusBuffer, L"%lu", Status);
74     PrintMessageStringV(3502, szStatusBuffer);
75 
76     if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Status, 0, (LPWSTR)&Buffer, 0, NULL))
77     {
78         ConPrintf(StdErr, L"\n%s", Buffer);
79         LocalFree(Buffer);
80     }
81 }
82 
83 static
84 BOOL
85 ValidateDeviceName(PWSTR DevName)
86 {
87     DWORD Len;
88 
89     Len = wcslen(DevName);
90     if (Len != 2)
91     {
92         return FALSE;
93     }
94 
95     if (!iswalpha(DevName[0]) || DevName[1] != L':')
96     {
97         return FALSE;
98     }
99 
100     return TRUE;
101 }
102 
103 INT
104 cmdUse(
105     INT argc,
106     WCHAR **argv)
107 {
108     DWORD Status, Len, Delete;
109 
110     if (argc == 2)
111     {
112         Status = EnumerateConnections(NULL);
113         if (Status == NO_ERROR)
114             PrintErrorMessage(ERROR_SUCCESS);
115         else
116             PrintError(Status);
117 
118         return 0;
119     }
120     else if (argc == 3)
121     {
122         if (!ValidateDeviceName(argv[2]))
123         {
124             PrintMessageStringV(3952, L"DeviceName");
125             return 1;
126         }
127 
128         Status = EnumerateConnections(argv[2]);
129         if (Status == NO_ERROR)
130             PrintErrorMessage(ERROR_SUCCESS);
131         else
132             PrintError(Status);
133 
134         return 0;
135     }
136 
137     Delete = 0;
138     if (_wcsicmp(argv[2], L"/DELETE") == 0)
139     {
140         Delete = 3;
141     }
142     else
143     {
144         if ((argv[2][0] != '*' && argv[2][1] != 0) &&
145             !ValidateDeviceName(argv[2]))
146         {
147             PrintMessageStringV(3952, L"DeviceName");
148             return 1;
149         }
150     }
151 
152     if (_wcsicmp(argv[3], L"/DELETE") == 0)
153     {
154         Delete = 2;
155     }
156 
157     if (Delete != 0)
158     {
159         if (!ValidateDeviceName(argv[Delete]) || argv[Delete][0] == L'*')
160         {
161             PrintMessageStringV(3952, L"DeviceName");
162             return 1;
163         }
164 
165         Status = WNetCancelConnection2(argv[Delete], CONNECT_UPDATE_PROFILE, FALSE);
166         if (Status != NO_ERROR)
167             PrintError(Status);
168 
169         return Status;
170     }
171     else
172     {
173         BOOL Persist = FALSE;
174         NETRESOURCE lpNet;
175         WCHAR Access[256];
176         DWORD OutFlags = 0, Size = ARRAYSIZE(Access);
177 
178         Len = wcslen(argv[3]);
179         if (Len < 4)
180         {
181             PrintMessageStringV(3952, L"Name");
182             return 1;
183         }
184 
185         if (argv[3][0] != L'\\' || argv[3][1] != L'\\')
186         {
187             PrintMessageStringV(3952, L"Name");
188             return 1;
189         }
190 
191         if (argc > 4)
192         {
193             LPWSTR Cpy;
194             Len = wcslen(argv[4]);
195             if (Len > 12)
196             {
197                 Cpy = HeapAlloc(GetProcessHeap(), 0, (Len + 1) * sizeof(WCHAR));
198                 if (Cpy)
199                 {
200                     INT i;
201                     for (i = 0; i < Len; ++i)
202                         Cpy[i] = towupper(argv[4][i]);
203 
204                     if (wcsstr(Cpy, L"/PERSISTENT:") == Cpy)
205                     {
206                         LPWSTR Arg = Cpy + 12;
207                         if (Len == 14 && Arg[0] == 'N' && Arg[1] == 'O')
208                         {
209                             Persist = FALSE;
210                         }
211                         else if (Len == 15 && Arg[0] == 'Y' && Arg[1] == 'E' && Arg[2] == 'S')
212                         {
213                             Persist = TRUE;
214                         }
215                         else
216                         {
217                             HeapFree(GetProcessHeap(), 0, Cpy);
218                             PrintMessageStringV(3952, L"Persistent");
219                             return 1;
220                         }
221                     }
222                     HeapFree(GetProcessHeap(), 0, Cpy);
223                 }
224             }
225 
226         }
227 
228         lpNet.dwType = RESOURCETYPE_DISK;
229         lpNet.lpLocalName = (argv[2][0] != L'*') ? argv[2] : NULL;
230         lpNet.lpRemoteName = argv[3];
231         lpNet.lpProvider = NULL;
232 
233         Status = WNetUseConnection(NULL, &lpNet, NULL, NULL, CONNECT_REDIRECT | (Persist ? CONNECT_UPDATE_PROFILE : 0), Access, &Size, &OutFlags);
234         if (argv[2][0] == L'*' && Status == NO_ERROR && OutFlags == CONNECT_LOCALDRIVE)
235             PrintMessageStringV(3919, argv[3], Access);
236         else if (Status != NO_ERROR)
237             PrintError(Status);
238 
239         return Status;
240     }
241 }
242