[NET/USE]
[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 #define COUNT_OF(a) (sizeof(a) / sizeof(a[0]))
13
14 static
15 DWORD
16 EnumerateConnections(LPCWSTR Local)
17 {
18 DWORD dRet;
19 HANDLE hEnum;
20 LPNETRESOURCE lpRes;
21 DWORD dSize = 0x1000;
22 DWORD dCount = -1;
23 LPNETRESOURCE lpCur;
24
25 ConPrintf(StdOut, L"%s\t\t\t%s\t\t\t\t%s\n", L"Local", L"Remote", L"Provider");
26
27 dRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, 0, NULL, &hEnum);
28 if (dRet != WN_SUCCESS)
29 {
30 return 1;
31 }
32
33 lpRes = HeapAlloc(GetProcessHeap(), 0, dSize);
34 if (!lpRes)
35 {
36 WNetCloseEnum(hEnum);
37 return 1;
38 }
39
40 do
41 {
42 dSize = 0x1000;
43 dCount = -1;
44
45 memset(lpRes, 0, dSize);
46 dRet = WNetEnumResource(hEnum, &dCount, lpRes, &dSize);
47 if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
48 {
49 lpCur = lpRes;
50 for (; dCount; dCount--)
51 {
52 if (!Local || wcsicmp(lpCur->lpLocalName, Local) == 0)
53 {
54 ConPrintf(StdOut, L"%s\t\t\t%s\t\t%s\n", lpCur->lpLocalName, lpCur->lpRemoteName, lpCur->lpProvider);
55 }
56
57 lpCur++;
58 }
59 }
60 } while (dRet != WN_NO_MORE_ENTRIES);
61
62 HeapFree(GetProcessHeap(), 0, lpRes);
63 WNetCloseEnum(hEnum);
64
65 return 0;
66 }
67
68 INT
69 cmdUse(
70 INT argc,
71 WCHAR **argv)
72 {
73 DWORD Status, Len;
74
75 if (argc == 2)
76 {
77 Status = EnumerateConnections(NULL);
78 ConPrintf(StdOut, L"Status: %lu\n", Status);
79 return 0;
80 }
81 else if (argc == 3)
82 {
83 Len = wcslen(argv[2]);
84 if (Len != 2)
85 {
86 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
87 return 1;
88 }
89
90 if (!iswalpha(argv[2][0]) || argv[2][1] != L':')
91 {
92 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
93 return 1;
94 }
95
96 Status = EnumerateConnections(argv[2]);
97 ConPrintf(StdOut, L"Status: %lu\n", Status);
98 return 0;
99 }
100
101 Len = wcslen(argv[2]);
102 if (Len != 1 && Len != 2)
103 {
104 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
105 ConPrintf(StdOut, L"Len: %lu\n", Len);
106 return 1;
107 }
108
109 if (Len == 2 && argv[2][1] != L':')
110 {
111 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
112 return 1;
113 }
114
115 if (argv[2][0] != L'*' && !iswalpha(argv[2][0]))
116 {
117 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
118 return 1;
119 }
120
121 if (wcsicmp(argv[3], L"/DELETE") == 0)
122 {
123 if (argv[2][0] == L'*')
124 {
125 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"DeviceName");
126 return 1;
127 }
128
129 return WNetCancelConnection2(argv[2], CONNECT_UPDATE_PROFILE, FALSE);
130 }
131 else
132 {
133 BOOL Persist = FALSE;
134 NETRESOURCE lpNet;
135 WCHAR Access[256];
136 DWORD OutFlags = 0, Size = COUNT_OF(Access);
137
138 Len = wcslen(argv[3]);
139 if (Len < 4)
140 {
141 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"Name");
142 return 1;
143 }
144
145 if (argv[3][0] != L'\\' || argv[3][1] != L'\\')
146 {
147 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"Name");
148 return 1;
149 }
150
151 if (argc > 4)
152 {
153 LPWSTR Cpy;
154 Len = wcslen(argv[4]);
155 if (Len > 12)
156 {
157 Cpy = HeapAlloc(GetProcessHeap(), 0, (Len + 1) * sizeof(WCHAR));
158 if (Cpy)
159 {
160 INT i;
161 for (i = 0; i < Len; ++i)
162 Cpy[i] = towupper(argv[4][i]);
163
164 if (wcsstr(Cpy, L"/PERSISTENT:") == Cpy)
165 {
166 LPWSTR Arg = Cpy + 12;
167 if (Len == 14 && Arg[0] == 'N' && Arg[1] == 'O')
168 {
169 Persist = FALSE;
170 }
171 else if (Len == 15 && Arg[0] == 'Y' && Arg[1] == 'E' && Arg[2] == 'S')
172 {
173 Persist = TRUE;
174 }
175 else
176 {
177 HeapFree(GetProcessHeap(), 0, Cpy);
178 ConResPrintf(StdErr, IDS_ERROR_INVALID_OPTION_VALUE, L"Persistent");
179 return 1;
180 }
181 }
182 HeapFree(GetProcessHeap(), 0, Cpy);
183 }
184 }
185
186 }
187
188 lpNet.dwType = RESOURCETYPE_DISK;
189 lpNet.lpLocalName = (argv[2][0] != L'*') ? argv[2] : NULL;
190 lpNet.lpRemoteName = argv[3];
191 lpNet.lpProvider = NULL;
192
193 Status = WNetUseConnection(NULL, &lpNet, NULL, NULL, CONNECT_REDIRECT | (Persist ? CONNECT_UPDATE_PROFILE : 0), Access, &Size, &OutFlags);
194 if (argv[2][0] == L'*' && Status == NO_ERROR && OutFlags == CONNECT_LOCALDRIVE)
195 ConPrintf(StdOut, L"%s is now connected to %s\n", argv[3], Access);
196 else if (Status != NO_ERROR)
197 {
198 LPWSTR Buffer;
199
200 ConPrintf(StdErr, L"The system error %d happened.\n", Status);
201
202 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Status, 0, (LPWSTR)&Buffer, 0, NULL))
203 {
204 ConPrintf(StdErr, L"\n%s\n", Buffer);
205 LocalFree(Buffer);
206 }
207 }
208
209 return Status;
210 }
211 }