[NET][MC] Move generic strings from net.exe to netmsg.dll.
[reactos.git] / base / applications / network / net / cmdUse.c
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 }