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