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