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
EnumerateConnections(LPCWSTR Local)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
PrintError(DWORD Status)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
ValidateDeviceName(PWSTR DevName)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
cmdUse(INT argc,WCHAR ** argv)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