xref: /reactos/base/applications/network/net/cmdUse.c (revision 01e5cb0c)
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     LPWSTR Buffer;
71 
72     ConResPrintf(StdErr, IDS_ERROR_SYSTEM_ERROR, Status);
73 
74     if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Status, 0, (LPWSTR)&Buffer, 0, NULL))
75     {
76         ConPrintf(StdErr, L"\n%s", Buffer);
77         LocalFree(Buffer);
78     }
79 }
80 
81 static
82 BOOL
83 ValidateDeviceName(PWSTR DevName)
84 {
85     DWORD Len;
86 
87     Len = wcslen(DevName);
88     if (Len != 2)
89     {
90         return FALSE;
91     }
92 
93     if (!iswalpha(DevName[0]) || DevName[1] != L':')
94     {
95         return FALSE;
96     }
97 
98     return TRUE;
99 }
100 
101 INT
102 cmdUse(
103     INT argc,
104     WCHAR **argv)
105 {
106     DWORD Status, Len, Delete;
107 
108     if (argc == 2)
109     {
110         Status = EnumerateConnections(NULL);
111         if (Status == NO_ERROR)
112             PrintErrorMessage(ERROR_SUCCESS);
113         else
114             PrintError(Status);
115 
116         return 0;
117     }
118     else if (argc == 3)
119     {
120         if (!ValidateDeviceName(argv[2]))
121         {
122             ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
123             return 1;
124         }
125 
126         Status = EnumerateConnections(argv[2]);
127         if (Status == NO_ERROR)
128             PrintErrorMessage(ERROR_SUCCESS);
129         else
130             PrintError(Status);
131 
132         return 0;
133     }
134 
135     Delete = 0;
136     if (wcsicmp(argv[2], L"/DELETE") == 0)
137     {
138         Delete = 3;
139     }
140     else
141     {
142         if ((argv[2][0] != '*' && argv[2][1] != 0) &&
143             !ValidateDeviceName(argv[2]))
144         {
145             ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
146             return 1;
147         }
148     }
149 
150     if (wcsicmp(argv[3], L"/DELETE") == 0)
151     {
152         Delete = 2;
153     }
154 
155     if (Delete != 0)
156     {
157         if (!ValidateDeviceName(argv[Delete]) || argv[Delete][0] == L'*')
158         {
159             ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
160             return 1;
161         }
162 
163         Status = WNetCancelConnection2(argv[Delete], CONNECT_UPDATE_PROFILE, FALSE);
164         if (Status != NO_ERROR)
165             PrintError(Status);
166 
167         return Status;
168     }
169     else
170     {
171         BOOL Persist = FALSE;
172         NETRESOURCE lpNet;
173         WCHAR Access[256];
174         DWORD OutFlags = 0, Size = ARRAYSIZE(Access);
175 
176         Len = wcslen(argv[3]);
177         if (Len < 4)
178         {
179             ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"Name");
180             return 1;
181         }
182 
183         if (argv[3][0] != L'\\' || argv[3][1] != L'\\')
184         {
185             ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"Name");
186             return 1;
187         }
188 
189         if (argc > 4)
190         {
191             LPWSTR Cpy;
192             Len = wcslen(argv[4]);
193             if (Len > 12)
194             {
195                 Cpy = HeapAlloc(GetProcessHeap(), 0, (Len + 1) * sizeof(WCHAR));
196                 if (Cpy)
197                 {
198                     INT i;
199                     for (i = 0; i < Len; ++i)
200                         Cpy[i] = towupper(argv[4][i]);
201 
202                     if (wcsstr(Cpy, L"/PERSISTENT:") == Cpy)
203                     {
204                         LPWSTR Arg = Cpy + 12;
205                         if (Len == 14 && Arg[0] == 'N' && Arg[1] == 'O')
206                         {
207                             Persist = FALSE;
208                         }
209                         else if (Len == 15 && Arg[0] == 'Y' && Arg[1] == 'E' && Arg[2] == 'S')
210                         {
211                             Persist = TRUE;
212                         }
213                         else
214                         {
215                             HeapFree(GetProcessHeap(), 0, Cpy);
216                             ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"Persistent");
217                             return 1;
218                         }
219                     }
220                     HeapFree(GetProcessHeap(), 0, Cpy);
221                 }
222             }
223 
224         }
225 
226         lpNet.dwType = RESOURCETYPE_DISK;
227         lpNet.lpLocalName = (argv[2][0] != L'*') ? argv[2] : NULL;
228         lpNet.lpRemoteName = argv[3];
229         lpNet.lpProvider = NULL;
230 
231         Status = WNetUseConnection(NULL, &lpNet, NULL, NULL, CONNECT_REDIRECT | (Persist ? CONNECT_UPDATE_PROFILE : 0), Access, &Size, &OutFlags);
232         if (argv[2][0] == L'*' && Status == NO_ERROR && OutFlags == CONNECT_LOCALDRIVE)
233             ConResPrintf(StdOut, IDS_USE_NOW_CONNECTED, argv[3], Access);
234         else if (Status != NO_ERROR)
235             PrintError(Status);
236 
237         return Status;
238     }
239 }
240