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 } 240