[HACKSSIGN]
[reactos.git] / rosapps / applications / cmdutils / rosvboxmgmt / rosvboxmgmt.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS VBox Shared Folders Management
4 * FILE: cmdutils/hackssign/client.c
5 * PURPOSE: Communicate with VBox mini redirector to deal with shared folders
6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7 */
8
9 #include <stdio.h>
10 #include <wchar.h>
11 #include <windows.h>
12
13 /* DON'T CHANGE ORDER!!!! */
14 PCWSTR devices[3] = { L"\\\\.\\VBoxMiniRdrDN", L"\\??\\VBoxMiniRdrDN", L"\\Device\\VBoxMiniRdr" };
15
16 /* Taken from VBox header */
17 #define _MRX_MAX_DRIVE_LETTERS 26
18 #define IOCTL_MRX_VBOX_BASE FILE_DEVICE_NETWORK_FILE_SYSTEM
19 #define _MRX_VBOX_CONTROL_CODE(request, method, access) \
20 CTL_CODE(IOCTL_MRX_VBOX_BASE, request, method, access)
21 #define IOCTL_MRX_VBOX_ADDCONN _MRX_VBOX_CONTROL_CODE(100, METHOD_BUFFERED, FILE_ANY_ACCESS)
22 #define IOCTL_MRX_VBOX_GETLIST _MRX_VBOX_CONTROL_CODE(103, METHOD_BUFFERED, FILE_ANY_ACCESS)
23 #define IOCTL_MRX_VBOX_GETGLOBALLIST _MRX_VBOX_CONTROL_CODE(104, METHOD_BUFFERED, FILE_ANY_ACCESS)
24 #define IOCTL_MRX_VBOX_START _MRX_VBOX_CONTROL_CODE(106, METHOD_BUFFERED, FILE_ANY_ACCESS)
25
26 BOOL performDevIoCtl(DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize)
27 {
28 short i;
29 BOOL ret;
30 DWORD lpBytesReturned;
31 HANDLE dev = INVALID_HANDLE_VALUE;
32
33 wprintf(L"Trying to open a VBoxSRV device\n");
34 for (i = 0; i < 3; ++i)
35 {
36 dev = CreateFile(devices[i],
37 GENERIC_READ | GENERIC_WRITE,
38 FILE_SHARE_READ | FILE_SHARE_WRITE,
39 NULL, OPEN_EXISTING, 0, NULL);
40 if (dev != INVALID_HANDLE_VALUE)
41 {
42 break;
43 }
44 }
45
46 if (dev == INVALID_HANDLE_VALUE)
47 {
48 return FALSE;
49 }
50
51 wprintf(L"%s opened.\n", devices[i]);
52
53 ret = DeviceIoControl(dev, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, &lpBytesReturned, NULL);
54 wprintf(L"Done: it %s with error: %lx\n", (ret != 0 ? L"succeed" : L"failed"), (ret != 0 ? ERROR_SUCCESS : GetLastError()));
55
56 CloseHandle(dev);
57
58 return ret;
59 }
60
61 int startVBoxSrv(void)
62 {
63 return (performDevIoCtl(IOCTL_MRX_VBOX_START, NULL, 0, NULL, 0) == FALSE);
64 }
65
66 int addConn(PCWSTR letter, PCWSTR path)
67 {
68 BOOL ret;
69 PWSTR inputBuffer;
70 DWORD inputBufferSize;
71
72 if (iswalpha(letter[0]) == 0)
73 {
74 wprintf(L"Invalid letter provided\n");
75 return 1;
76 }
77
78 if (wcschr(path, L'\\') != NULL)
79 {
80 wprintf(L"Only give the name of a share\n");
81 return 1;
82 }
83
84 inputBufferSize = (wcslen(path) + wcslen(devices[2]) + wcslen(L"\\;Z:\\vboxsvr\\")) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
85 inputBuffer = malloc(inputBufferSize);
86 if (inputBuffer == NULL)
87 {
88 wprintf(L"Memory failure\n");
89 return 1;
90 }
91
92 swprintf(inputBuffer, L"%s\\;%c:\\vboxsvr\\%s", devices[2], towupper(letter[0]), path);
93 wprintf(L"Will create the following connection: %s\n", inputBuffer);
94 ret = performDevIoCtl(IOCTL_MRX_VBOX_ADDCONN, inputBuffer, inputBufferSize, NULL, 0);
95 free(inputBuffer);
96
97 return (ret == FALSE);
98 }
99
100 int getList(void)
101 {
102 short i;
103 BOOL ret;
104 DWORD outputBufferSize;
105 char outputBuffer[_MRX_MAX_DRIVE_LETTERS];
106
107 outputBufferSize = sizeof(outputBuffer);
108 ret = performDevIoCtl(IOCTL_MRX_VBOX_GETLIST, NULL, 0, &outputBuffer, outputBufferSize);
109 if (ret == FALSE)
110 {
111 return 1;
112 }
113
114 for (i = 0; i < _MRX_MAX_DRIVE_LETTERS; i += 2)
115 {
116 wprintf(L"%c: %s\t%c: %s\n", 'A' + i, (outputBuffer[i] == 0 ? L"FALSE" : L"TRUE"),
117 'A' + (i + 1), (outputBuffer[i + 1] == 0 ? L"FALSE" : L"TRUE"));
118 }
119
120 return 0;
121 }
122
123 int getGlobalList(void)
124 {
125 short i;
126 BOOL ret;
127 DWORD outputBufferSize;
128 char outputBuffer[_MRX_MAX_DRIVE_LETTERS];
129
130 outputBufferSize = sizeof(outputBuffer);
131 memset(outputBuffer, 0, outputBufferSize);
132 ret = performDevIoCtl(IOCTL_MRX_VBOX_GETGLOBALLIST, NULL, 0, &outputBuffer, outputBufferSize);
133 if (ret == FALSE)
134 {
135 return 1;
136 }
137
138 for (i = 0; i < _MRX_MAX_DRIVE_LETTERS; i += 2)
139 {
140 wprintf(L"%c: %s\t%c: %s\n", 'A' + i, (outputBuffer[i] & 0x80 ? L"Active" : L"Inactive"),
141 'A' + (i + 1), (outputBuffer[i + 1] & 0x80 ? L"Active" : L"Inactive"));
142 }
143
144 return 0;
145 }
146
147 void printUsage(void)
148 {
149 wprintf(L"ReactOS VBox Shared Folders Management\n");
150 wprintf(L"\tstart: start the VBox Shared folders (mandatory prior any operation!)\n");
151 wprintf(L"\taddconn <letter> <share name>: add a connection\n");
152 wprintf(L"\tgetlist: list connections\n");
153 wprintf(L"\tgetgloballist: list available shares\n");
154 }
155
156 int wmain(int argc, wchar_t *argv[])
157 {
158 PCWSTR cmd;
159
160 if (argc == 1)
161 {
162 printUsage();
163 return 0;
164 }
165
166 cmd = argv[1];
167
168 if (_wcsicmp(cmd, L"start") == 0)
169 {
170 return startVBoxSrv();
171 }
172 else if (_wcsicmp(cmd, L"addconn") == 0)
173 {
174 if (argc < 4)
175 {
176 printUsage();
177 return 0;
178 }
179
180 return addConn(argv[2], argv[3]);
181 }
182 else if (_wcsicmp(cmd, L"getlist") == 0)
183 {
184 return getList();
185 }
186 else if (_wcsicmp(cmd, L"getgloballist") == 0)
187 {
188 return getGlobalList();
189 }
190 else
191 {
192 printUsage();
193 return 0;
194 }
195 }