1 // SoftEther VPN Source Code - Stable Edition Repository
2 // SeLow: SoftEther Lightweight Network Protocol
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100 
101 
102 // SeLowUser.c
103 // SoftEther Lightweight Network Protocol User-mode Library
104 
105 #include <GlobalConst.h>
106 
107 #ifdef	WIN32
108 
109 #include <windows.h>
110 #include <stdio.h>
111 #include <stdlib.h>
112 #include <string.h>
113 #include <wchar.h>
114 #include <stdarg.h>
115 #include <time.h>
116 #include <errno.h>
117 #include <Mayaqua/Mayaqua.h>
118 #include <Cedar/Cedar.h>
119 
120 // Load the drivers hive
SuLoadDriversHive()121 bool SuLoadDriversHive()
122 {
123 	wchar_t config_dir[MAX_PATH];
124 	wchar_t filename[MAX_PATH];
125 	if (MsIsWindows10() == false)
126 	{
127 		return false;
128 	}
129 
130 	MsEnablePrivilege(SE_RESTORE_NAME, true);
131 	MsEnablePrivilege(SE_BACKUP_NAME, true);
132 
133 	CombinePathW(config_dir, sizeof(config_dir), MsGetSystem32DirW(), L"config");
134 	CombinePathW(filename, sizeof(filename), config_dir, L"DRIVERS");
135 
136 	return MsRegLoadHive(REG_LOCAL_MACHINE, L"DRIVERS", filename);
137 }
138 
139 // Unload the drivers hive
SuUnloadDriversHive()140 bool SuUnloadDriversHive()
141 {
142 	// todo: always failed.
143 	if (MsIsWindows10() == false)
144 	{
145 		return false;
146 	}
147 
148 	return MsRegUnloadHive(REG_LOCAL_MACHINE, L"DRIVERS");
149 }
150 
151 // Delete garbage inf files
SuDeleteGarbageInfs()152 void SuDeleteGarbageInfs()
153 {
154 	void *wow;
155 	bool load_hive = false;
156 	Debug("SuDeleteGarbageInfs()\n");
157 
158 	wow = MsDisableWow64FileSystemRedirection();
159 
160 	load_hive = SuLoadDriversHive();
161 	Debug("SuLoadDriversHive: %u\n", load_hive);
162 
163 	SuDeleteGarbageInfsInner();
164 
165 	/*
166 	if (load_hive)
167 	{
168 		Debug("SuUnloadDriversHive: %u\n", SuUnloadDriversHive());
169 	}*/
170 
171 	MsRestoreWow64FileSystemRedirection(wow);
172 }
SuDeleteGarbageInfsInner()173 void SuDeleteGarbageInfsInner()
174 {
175 	char *base_key_name = "DRIVERS\\DriverDatabase\\DriverPackages";
176 	TOKEN_LIST *keys;
177 	HINSTANCE hSetupApiDll = NULL;
178 	BOOL (WINAPI *_SetupUninstallOEMInfA)(PCSTR, DWORD, PVOID) = NULL;
179 
180 	if (MsIsWindows10() == false)
181 	{
182 		return;
183 	}
184 
185 	hSetupApiDll = LoadLibraryA("setupapi.dll");
186 	if (hSetupApiDll == NULL)
187 	{
188 		return;
189 	}
190 
191 	_SetupUninstallOEMInfA =
192 		(UINT (__stdcall *)(PCSTR,DWORD,PVOID))
193 		GetProcAddress(hSetupApiDll, "SetupUninstallOEMInfA");
194 
195 	if (_SetupUninstallOEMInfA != NULL)
196 	{
197 		keys = MsRegEnumKeyEx2(REG_LOCAL_MACHINE, base_key_name, false, true);
198 
199 		if (keys != NULL)
200 		{
201 			char full_key[MAX_PATH];
202 			UINT i;
203 
204 			for (i = 0;i < keys->NumTokens;i++)
205 			{
206 				char *oem_name, *inf_name, *provider;
207 
208 				Format(full_key, sizeof(full_key), "%s\\%s", base_key_name, keys->Token[i]);
209 
210 				oem_name = MsRegReadStrEx2(REG_LOCAL_MACHINE, full_key, "", false, true);
211 				inf_name = MsRegReadStrEx2(REG_LOCAL_MACHINE, full_key, "InfName", false, true);
212 				provider = MsRegReadStrEx2(REG_LOCAL_MACHINE, full_key, "Provider", false, true);
213 
214 				if (IsEmptyStr(oem_name) == false && IsEmptyStr(inf_name) == false)
215 				{
216 					if (StartWith(oem_name, "oem"))
217 					{
218 						if (StartWith(inf_name, "selow"))
219 						{
220 							if (InStr(provider, "softether"))
221 							{
222 								Debug("Delete OEM INF %s (%s): %u\n",
223 									oem_name, inf_name,
224 									_SetupUninstallOEMInfA(oem_name, 0x00000001, NULL));
225 							}
226 						}
227 					}
228 				}
229 
230 				Free(oem_name);
231 				Free(inf_name);
232 				Free(provider);
233 			}
234 
235 			FreeToken(keys);
236 		}
237 	}
238 
239 	if (hSetupApiDll != NULL)
240 	{
241 		FreeLibrary(hSetupApiDll);
242 	}
243 }
244 
245 // Install the driver
SuInstallDriver(bool force)246 bool SuInstallDriver(bool force)
247 {
248 	bool ret;
249 	void *wow;
250 
251 	wow = MsDisableWow64FileSystemRedirection();
252 
253 	ret = SuInstallDriverInner(force);
254 
255 	MsRestoreWow64FileSystemRedirection(wow);
256 
257 	return ret;
258 }
SuInstallDriverInner(bool force)259 bool SuInstallDriverInner(bool force)
260 {
261 	wchar_t sys_fullpath[MAX_PATH];
262 	UINT current_sl_ver = 0;
263 	bool ret = false;
264 	wchar_t src_cat[MAX_PATH];
265 	wchar_t src_inf[MAX_PATH];
266 	wchar_t src_sys[MAX_PATH];
267 	wchar_t dst_cat[MAX_PATH];
268 	wchar_t dst_inf[MAX_PATH];
269 	wchar_t dst_sys[MAX_PATH];
270 	wchar_t tmp_dir[MAX_PATH];
271 	char *cpu_type = MsIsX64() ? "x64" : "x86";
272 
273 	if (SuIsSupportedOs(true) == false)
274 	{
275 		// Unsupported OS
276 		return false;
277 	}
278 
279 	CombinePathW(tmp_dir, sizeof(tmp_dir), MsGetWindowsDirW(), L"Temp");
280 	MakeDirExW(tmp_dir);
281 
282 	UniStrCat(tmp_dir, sizeof(tmp_dir), L"\\selowtmp");
283 	MakeDirExW(tmp_dir);
284 
285 	// Confirm whether the driver is currently installed
286 	CombinePathW(sys_fullpath, sizeof(sys_fullpath), MsGetSystem32DirW(), L"drivers\\SeLow_%S.sys");
287 	UniFormat(sys_fullpath, sizeof(sys_fullpath), sys_fullpath, cpu_type);
288 
289 	if (IsFileExistsW(sys_fullpath))
290 	{
291 		char *path;
292 
293 		// Read the current version from the registry
294 		current_sl_ver = MsRegReadIntEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME,
295 			(MsIsWindows10() ? SL_REG_VER_VALUE_WIN10 : SL_REG_VER_VALUE),
296 			false, true);
297 
298 		path = MsRegReadStrEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME, "ImagePath", false, true);
299 
300 		if (IsEmptyStr(path) || IsFileExists(path) == false || MsIsServiceInstalled(SL_PROTOCOL_NAME) == false)
301 		{
302 			current_sl_ver = 0;
303 		}
304 
305 		Free(path);
306 	}
307 
308 	if (force == false && current_sl_ver >= SL_VER)
309 	{
310 		// Newer version has already been installed
311 		Debug("Newer SeLow is Installed. %u >= %u\n", current_sl_ver, SL_VER);
312 		return true;
313 	}
314 
315 	// Copy necessary files to a temporary directory
316 	UniFormat(src_sys, sizeof(src_sys), L"|DriverPackages\\%S\\%S\\SeLow_%S.sys",
317 		(MsIsWindows10() ? "SeLow_Win10" : "SeLow_Win8"),
318 		cpu_type, cpu_type);
319 	if (MsIsWindows8() == false)
320 	{
321 		// Windows Vista and Windows 7 uses SHA-1 catalog files
322 		UniFormat(src_cat, sizeof(src_cat), L"|DriverPackages\\SeLow_Win8\\%S\\inf.cat", cpu_type);
323 	}
324 	else
325 	{
326 		// Windows 8 or above uses SHA-256 catalog files
327 		UniFormat(src_cat, sizeof(src_cat), L"|DriverPackages\\SeLow_Win8\\%S\\inf2.cat", cpu_type);
328 
329 		if (MsIsWindows10())
330 		{
331 			// Windows 10 uses WHQL catalog files
332 			UniFormat(src_cat, sizeof(src_cat), L"|DriverPackages\\SeLow_Win10\\%S\\SeLow_Win10_%S.cat", cpu_type, cpu_type);
333 		}
334 	}
335 	UniFormat(src_inf, sizeof(src_inf), L"|DriverPackages\\%S\\%S\\SeLow_%S.inf",
336 		(MsIsWindows10() ? "SeLow_Win10" : "SeLow_Win8"),
337 		cpu_type, cpu_type);
338 
339 	UniFormat(dst_sys, sizeof(dst_cat), L"%s\\SeLow_%S.sys", tmp_dir, cpu_type);
340 	UniFormat(dst_cat, sizeof(dst_cat), L"%s\\SeLow_%S_%S.cat", tmp_dir,
341 		(MsIsWindows10() ? "Win10" : "Win8"),
342 		cpu_type);
343 
344 	UniFormat(dst_inf, sizeof(dst_inf), L"%s\\SeLow_%S.inf", tmp_dir, cpu_type);
345 
346 	if (FileCopyW(src_sys, dst_sys) &&
347 		FileCopyW(src_cat, dst_cat) &&
348 		FileCopyW(src_inf, dst_inf))
349 	{
350 		NO_WARNING *nw;
351 
352 		nw = MsInitNoWarningEx(SL_USER_AUTO_PUSH_TIMER);
353 
354 		if (MsIsWindows10())
355 		{
356 			if (MsIsServiceInstalled(SL_PROTOCOL_NAME) == false && MsIsServiceRunning(SL_PROTOCOL_NAME) == false)
357 			{
358 				// On Windows 10, if there are no SwLow service installed, then uinstall the protocol driver first.
359 				// TODO: currently do nothing. On some versions of Windows 10 beta builds it is necessary to do something...
360 			}
361 		}
362 
363 		if (MsIsWindows10())
364 		{
365 			// Delete garbage INFs
366 			SuDeleteGarbageInfs();
367 		}
368 
369 		// Call the installer
370 		if (InstallNdisProtocolDriver(dst_inf, L"SeLow", SL_USER_INSTALL_LOCK_TIMEOUT) == false)
371 		{
372 			Debug("InstallNdisProtocolDriver Error.\n");
373 		}
374 		else
375 		{
376 			Debug("InstallNdisProtocolDriver Ok.\n");
377 
378 			// Copy manually because there are cases where .sys file is not copied successfully for some reason
379 			Debug("SuCopySysFile from %S to %s: ret = %u\n", src_sys, sys_fullpath, SuCopySysFile(src_sys, sys_fullpath));
380 
381 			ret = true;
382 
383 			// Write the version number into the registry
384 			MsRegWriteIntEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME,
385 				(MsIsWindows10() ? SL_REG_VER_VALUE_WIN10 : SL_REG_VER_VALUE),
386 				SL_VER, false, true);
387 
388 			// Set to automatic startup
389 			MsRegWriteIntEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME, "Start", SERVICE_SYSTEM_START, false, true);
390 		}
391 
392 		MsFreeNoWarning(nw);
393 	}
394 	else
395 	{
396 		Debug("Fail Copying Files.\n");
397 	}
398 
399 	if (ret)
400 	{
401 		// If the service is installed this time, start and wait until the enumeration is completed
402 		SuFree(SuInitEx(180 * 1000));
403 	}
404 
405 	return ret;
406 }
407 
408 // Copy a sys file
SuCopySysFile(wchar_t * src,wchar_t * dst)409 bool SuCopySysFile(wchar_t *src, wchar_t *dst)
410 {
411 	wchar_t dst_rename[MAX_PATH];
412 	UINT i;
413 	if (src == NULL || dst == NULL)
414 	{
415 		return false;
416 	}
417 	if (FileCopyW(src, dst))
418 	{
419 		for (i = 1;i <= 100;i++)
420 		{
421 			UniFormat(dst_rename, sizeof(dst_rename), L"%s.old%u", dst, i);
422 
423 			FileDeleteW(dst_rename);
424 		}
425 
426 		return true;
427 	}
428 
429 	for (i = 1;;i++)
430 	{
431 		UniFormat(dst_rename, sizeof(dst_rename), L"%s.old%u", dst, i);
432 
433 		if (IsFileExistsW(dst_rename) == false)
434 		{
435 			break;
436 		}
437 
438 		if (i >= 100)
439 		{
440 			return false;
441 		}
442 	}
443 
444 	if (MoveFileW(dst, dst_rename) == false)
445 	{
446 		return false;
447 	}
448 
449 	if (FileCopyW(src, dst))
450 	{
451 		for (i = 1;i <= 100;i++)
452 		{
453 			UniFormat(dst_rename, sizeof(dst_rename), L"%s.old%u", dst, i);
454 
455 			FileDeleteW(dst_rename);
456 		}
457 
458 		return true;
459 	}
460 
461 	MoveFileW(dst_rename, dst);
462 
463 	return false;
464 }
465 
466 // Get whether the current OS is supported by SeLow
SuIsSupportedOs(bool on_install)467 bool SuIsSupportedOs(bool on_install)
468 {
469 	if (MsRegReadIntEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME, "EnableSeLow", false, true) != 0)
470 	{
471 		// Force enable
472 		return true;
473 	}
474 
475 	if (MsRegReadIntEx2(REG_LOCAL_MACHINE, SL_REG_KEY_NAME, "DisableSeLow", false, true) != 0)
476 	{
477 		// Force disable
478 		return false;
479 	}
480 
481 	if (MsIsWindows10())
482 	{
483 		// Windows 10 or later are always supported.
484 		return true;
485 	}
486 
487 	if (on_install)
488 	{
489 		// If Microsoft Routing and Remote Access service is running,
490 		// then return false.
491 		if (MsIsServiceRunning("RemoteAccess"))
492 		{
493 			return false;
494 		}
495 	}
496 
497 	// If the Su driver is currently running,
498 	// then return true.
499 	if (MsIsServiceRunning(SL_PROTOCOL_NAME))
500 	{
501 		return true;
502 	}
503 
504 	// Currently Windows 8.1 or later are supported
505 	if (MsIsWindows81() == false)
506 	{
507 		return false;
508 	}
509 
510 	if (on_install == false)
511 	{
512 		// If Microsoft Routing and Remote Access service is running,
513 		// then return false.
514 		if (MsIsServiceRunning("RemoteAccess"))
515 		{
516 			return false;
517 		}
518 	}
519 
520 	return true;
521 }
522 
523 // Write the next packet to the driver
SuPutPacket(SU_ADAPTER * a,void * buf,UINT size)524 bool SuPutPacket(SU_ADAPTER *a, void *buf, UINT size)
525 {
526 	// Validate arguments
527 	if (a == NULL)
528 	{
529 		return false;
530 	}
531 	if (a->Halt)
532 	{
533 		return false;
534 	}
535 	if (size > MAX_PACKET_SIZE)
536 	{
537 		return false;
538 	}
539 
540 	// First, examine whether the current buffer is full
541 	if ((SL_NUM_PACKET(a->PutBuffer) >= SL_MAX_PACKET_EXCHANGE) ||
542 		(buf == NULL && SL_NUM_PACKET(a->PutBuffer) != 0))
543 	{
544 		// Write all current packets to the driver
545 		if (SuPutPacketsToDriver(a) == false)
546 		{
547 			return false;
548 		}
549 
550 		SL_NUM_PACKET(a->PutBuffer) = 0;
551 	}
552 
553 	// Add the next packet to the buffer
554 	if (buf != NULL)
555 	{
556 		UINT i = SL_NUM_PACKET(a->PutBuffer);
557 		SL_NUM_PACKET(a->PutBuffer)++;
558 
559 		SL_SIZE_OF_PACKET(a->PutBuffer, i) = size;
560 		Copy(SL_ADDR_OF_PACKET(a->PutBuffer, i), buf, size);
561 
562 		Free(buf);
563 	}
564 
565 	return true;
566 }
567 
568 // Write all current packets to the driver
SuPutPacketsToDriver(SU_ADAPTER * a)569 bool SuPutPacketsToDriver(SU_ADAPTER *a)
570 {
571 	DWORD write_size;
572 	// Validate arguments
573 	if (a == NULL)
574 	{
575 		return false;
576 	}
577 	if (a->Halt)
578 	{
579 		return false;
580 	}
581 
582 	if (WriteFile(a->hFile, a->PutBuffer, SL_EXCHANGE_BUFFER_SIZE, &write_size, NULL) == false)
583 	{
584 		a->Halt = true;
585 
586 		SuCloseAdapterHandleInner(a);
587 		return false;
588 	}
589 
590 	if (write_size != SL_EXCHANGE_BUFFER_SIZE)
591 	{
592 		a->Halt = true;
593 		return false;
594 	}
595 
596 	return true;
597 }
598 
599 // Read the next packet from the driver
SuGetNextPacket(SU_ADAPTER * a,void ** buf,UINT * size)600 bool SuGetNextPacket(SU_ADAPTER *a, void **buf, UINT *size)
601 {
602 	// Validate arguments
603 	if (a == NULL || buf == NULL || size == NULL)
604 	{
605 		return false;
606 	}
607 
608 	if (a->Halt)
609 	{
610 		return false;
611 	}
612 
613 	while (true)
614 	{
615 		if (a->CurrentPacketCount < SL_NUM_PACKET(a->GetBuffer))
616 		{
617 			// There are still packets that have been already read
618 			*size = SL_SIZE_OF_PACKET(a->GetBuffer, a->CurrentPacketCount);
619 			*buf = Malloc(*size);
620 			Copy(*buf, SL_ADDR_OF_PACKET(a->GetBuffer, a->CurrentPacketCount), *size);
621 
622 			// Increment the packet number
623 			a->CurrentPacketCount++;
624 
625 			return true;
626 		}
627 		else
628 		{
629 			// Read the next packet from the driver
630 			if (SuGetPacketsFromDriver(a) == false)
631 			{
632 				return false;
633 			}
634 
635 			if (SL_NUM_PACKET(a->GetBuffer) == 0)
636 			{
637 				// Packet is not received yet
638 				*buf = NULL;
639 				*size = 0;
640 				return true;
641 			}
642 
643 			a->CurrentPacketCount = 0;
644 		}
645 	}
646 }
647 
648 // Read the next packet from the driver
SuGetPacketsFromDriver(SU_ADAPTER * a)649 bool SuGetPacketsFromDriver(SU_ADAPTER *a)
650 {
651 	DWORD read_size;
652 	// Validate arguments
653 	if (a == NULL)
654 	{
655 		return false;
656 	}
657 
658 	if (a->Halt)
659 	{
660 		return false;
661 	}
662 
663 	if (ReadFile(a->hFile, a->GetBuffer, SL_EXCHANGE_BUFFER_SIZE, &read_size, NULL) == false)
664 	{
665 		a->Halt = true;
666 
667 		SuCloseAdapterHandleInner(a);
668 		return false;
669 	}
670 
671 	if (read_size != SL_EXCHANGE_BUFFER_SIZE)
672 	{
673 		a->Halt = true;
674 		return false;
675 	}
676 
677 	return true;
678 }
679 
680 // Close the adapter
SuCloseAdapter(SU_ADAPTER * a)681 void SuCloseAdapter(SU_ADAPTER *a)
682 {
683 	// Validate arguments
684 	if (a == NULL)
685 	{
686 		return;
687 	}
688 
689 	if (a->hEvent != NULL)
690 	{
691 		CloseHandle(a->hEvent);
692 	}
693 
694 	if (a->hFile != INVALID_HANDLE_VALUE)
695 	{
696 		CloseHandle(a->hFile);
697 		a->hFile = INVALID_HANDLE_VALUE;
698 	}
699 
700 	Free(a);
701 }
702 
703 // Close the adapter handle
SuCloseAdapterHandleInner(SU_ADAPTER * a)704 void SuCloseAdapterHandleInner(SU_ADAPTER *a)
705 {
706 	return;//////////// ****************
707 	// Validate arguments
708 	if (a == NULL)
709 	{
710 		return;
711 	}
712 
713 	if (a->hFile != INVALID_HANDLE_VALUE)
714 	{
715 		CloseHandle(a->hFile);
716 		a->hFile = INVALID_HANDLE_VALUE;
717 	}
718 }
719 
720 // Open the adapter
SuOpenAdapter(SU * u,char * adapter_id)721 SU_ADAPTER *SuOpenAdapter(SU *u, char *adapter_id)
722 {
723 	char filename[MAX_PATH];
724 	void *h;
725 	SU_ADAPTER *a;
726 	SL_IOCTL_EVENT_NAME t;
727 	UINT read_size;
728 	// Validate arguments
729 	if (u == NULL || adapter_id == NULL)
730 	{
731 		return NULL;
732 	}
733 
734 	Format(filename, sizeof(filename), SL_ADAPTER_DEVICE_FILENAME_WIN32, adapter_id);
735 
736 	h = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE,
737 		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
738 
739 	if (h == INVALID_HANDLE_VALUE)
740 	{
741 		Debug("Create File %s failed. %u\n", filename, GetLastError());
742 		return NULL;
743 	}
744 	else
745 	{
746 		Debug("Create File %s ok.\n", filename);
747 	}
748 
749 	a = ZeroMalloc(sizeof(SU_ADAPTER));
750 
751 	StrCpy(a->AdapterId, sizeof(a->AdapterId), adapter_id);
752 	StrCpy(a->DeviceName, sizeof(a->DeviceName), filename);
753 
754 	a->hFile = h;
755 
756 	Zero(&t, sizeof(t));
757 
758 	// Get the event name
759 	if (DeviceIoControl(h, SL_IOCTL_GET_EVENT_NAME, &t, sizeof(t), &t, sizeof(t), &read_size, NULL) == false)
760 	{
761 		// Acquisition failure
762 		SuCloseAdapter(a);
763 		return NULL;
764 	}
765 
766 	Debug("Event Name: %s\n", t.EventNameWin32);
767 
768 	// Get the event
769 	a->hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, t.EventNameWin32);
770 
771 	if (a->hEvent == NULL)
772 	{
773 		// Acquisition failure
774 		SuCloseAdapter(a);
775 		return NULL;
776 	}
777 
778 	return a;
779 }
780 
781 // Enumerate adapters
SuEnumAdapters(SU * u)782 TOKEN_LIST *SuEnumAdapters(SU *u)
783 {
784 	UINT i;
785 	UINT ret_size;
786 	TOKEN_LIST *ret;
787 	// Validate arguments
788 	if (u == NULL)
789 	{
790 		return NullToken();
791 	}
792 
793 	Zero(&u->AdapterInfoList, sizeof(u->AdapterInfoList));
794 	if (ReadFile(u->hFile, &u->AdapterInfoList, sizeof(u->AdapterInfoList),
795 		&ret_size, NULL) == false ||
796 		u->AdapterInfoList.Signature != SL_SIGNATURE)
797 	{
798 		Debug("SuEnumAdapters: ReadFile error.\n");
799 		return NullToken();
800 	}
801 
802 	ret = ZeroMalloc(sizeof(TOKEN_LIST));
803 
804 	ret->NumTokens = u->AdapterInfoList.NumAdapters;
805 	ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
806 	Debug("SuEnumAdapters: u->AdapterInfoList.NumAdapters = %u\n", u->AdapterInfoList.NumAdapters);
807 
808 	for (i = 0;i < ret->NumTokens;i++)
809 	{
810 		ret->Token[i] = CopyUniToStr(u->AdapterInfoList.Adapters[i].AdapterId);
811 
812 		UniPrint(L"%s %u %S\n",
813 			u->AdapterInfoList.Adapters[i].AdapterId,
814 			u->AdapterInfoList.Adapters[i].MtuSize,
815 			u->AdapterInfoList.Adapters[i].FriendlyName);
816 	}
817 
818 	return ret;
819 }
820 
821 // Create an adapters list
SuGetAdapterList(SU * u)822 LIST *SuGetAdapterList(SU *u)
823 {
824 	LIST *ret;
825 	UINT read_size;
826 	UINT i;
827 	// Validate arguments
828 	if (u == NULL)
829 	{
830 		return NULL;
831 	}
832 
833 	ret = NewList(SuCmpAdaterList);
834 
835 	// Enumerate adapters
836 	Zero(&u->AdapterInfoList, sizeof(u->AdapterInfoList));
837 	if (ReadFile(u->hFile, &u->AdapterInfoList, sizeof(u->AdapterInfoList),
838 		&read_size, NULL) == false ||
839 		u->AdapterInfoList.Signature != SL_SIGNATURE)
840 	{
841 		SuFreeAdapterList(ret);
842 		return NULL;
843 	}
844 
845 	for (i = 0;i < u->AdapterInfoList.NumAdapters;i++)
846 	{
847 		SL_ADAPTER_INFO *info = &u->AdapterInfoList.Adapters[i];
848 		SU_ADAPTER_LIST *a = SuAdapterInfoToAdapterList(info);
849 
850 		if (a != NULL)
851 		{
852 			Add(ret, a);
853 		}
854 	}
855 
856 	// Sort
857 	Sort(ret);
858 
859 	return ret;
860 }
861 
862 // Comparison function of the adapter list
SuCmpAdaterList(void * p1,void * p2)863 int SuCmpAdaterList(void *p1, void *p2)
864 {
865 	int r;
866 	SU_ADAPTER_LIST *a1, *a2;
867 	if (p1 == NULL || p2 == NULL)
868 	{
869 		return 0;
870 	}
871 	a1 = *(SU_ADAPTER_LIST **)p1;
872 	a2 = *(SU_ADAPTER_LIST **)p2;
873 	if (a1 == NULL || a2 == NULL)
874 	{
875 		return 0;
876 	}
877 
878 	r = StrCmpi(a1->SortKey, a2->SortKey);
879 	if (r != 0)
880 	{
881 		return 0;
882 	}
883 
884 	return StrCmpi(a1->Guid, a2->Guid);
885 }
886 
887 // Release the adapter list
SuFreeAdapterList(LIST * o)888 void SuFreeAdapterList(LIST *o)
889 {
890 	UINT i;
891 	// Validate arguments
892 	if (o == NULL)
893 	{
894 		return;
895 	}
896 
897 	for (i = 0;i < LIST_NUM(o);i++)
898 	{
899 		SU_ADAPTER_LIST *a = LIST_DATA(o, i);
900 
901 		Free(a);
902 	}
903 
904 	ReleaseList(o);
905 }
906 
907 // Create an adapter list item
SuAdapterInfoToAdapterList(SL_ADAPTER_INFO * info)908 SU_ADAPTER_LIST *SuAdapterInfoToAdapterList(SL_ADAPTER_INFO *info)
909 {
910 	SU_ADAPTER_LIST t;
911 	char tmp[MAX_SIZE];
912 	// Validate arguments
913 	if (info == NULL)
914 	{
915 		return NULL;
916 	}
917 
918 	Zero(&t, sizeof(t));
919 	Copy(&t.Info, info, sizeof(SL_ADAPTER_INFO));
920 
921 	UniToStr(tmp, sizeof(tmp), info->AdapterId);
922 	if (IsEmptyStr(tmp) || IsEmptyStr(info->FriendlyName) || StartWith(tmp, SL_ADAPTER_ID_PREFIX) == false)
923 	{
924 		// Name is invalid
925 		return NULL;
926 	}
927 
928 	// GUID (Part after "SELOW_A_" prefix)
929 	StrCpy(t.Guid, sizeof(t.Guid), tmp + StrLen(SL_ADAPTER_ID_PREFIX));
930 
931 	// Name
932 	StrCpy(t.Name, sizeof(t.Name), tmp);
933 
934 	// Key for sort
935 	if (GetClassRegKeyWin32(t.SortKey, sizeof(t.SortKey), tmp, sizeof(tmp), t.Guid) == false)
936 	{
937 		// Can not be found
938 		return NULL;
939 	}
940 
941 	return Clone(&t, sizeof(t));
942 }
943 
944 // Initialize the driver
SuInit()945 SU *SuInit()
946 {
947 	return SuInitEx(0);
948 }
SuInitEx(UINT wait_for_bind_complete_tick)949 SU *SuInitEx(UINT wait_for_bind_complete_tick)
950 {
951 	void *h;
952 	SU *u;
953 	UINT read_size;
954 	bool flag = false;
955 	UINT64 giveup_tick = 0;
956 	static bool flag2 = false; // flag2 must be global
957 
958 	if (SuIsSupportedOs(false) == false)
959 	{
960 		// Unsupported OS
961 		return NULL;
962 	}
963 
964 LABEL_RETRY:
965 
966 	// Open the device driver
967 	h = CreateFileA(SL_BASIC_DEVICE_FILENAME_WIN32, GENERIC_READ | GENERIC_WRITE,
968 		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
969 
970 	if (h == INVALID_HANDLE_VALUE)
971 	{
972 		Debug("CreateFileA(%s) Failed.\n", SL_BASIC_DEVICE_FILENAME_WIN32);
973 
974 		// Start the service if it fails to start the device driver
975 		if (flag == false)
976 		{
977 			if (MsStartService(SL_PROTOCOL_NAME) == false)
978 			{
979 				Debug("MsStartService(%s) Failed.\n", SL_PROTOCOL_NAME);
980 
981 				if (MsIsWindows10())
982 				{
983 					if (flag2 == false)
984 					{
985 						flag2 = true;
986 
987 						if (SuInstallDriver(true))
988 						{
989 							goto LABEL_RETRY;
990 						}
991 					}
992 				}
993 			}
994 			else
995 			{
996 				Debug("MsStartService(%s) Ok.\n", SL_PROTOCOL_NAME);
997 				flag = true;
998 
999 				goto LABEL_RETRY;
1000 			}
1001 		}
1002 		return NULL;
1003 	}
1004 
1005 	//Debug("CreateFileA(%s) Ok.\n", SL_BASIC_DEVICE_FILENAME_WIN32);
1006 
1007 	u = ZeroMalloc(sizeof(SU));
1008 
1009 	giveup_tick = Tick64() + (UINT64)wait_for_bind_complete_tick;
1010 
1011 	if (wait_for_bind_complete_tick == 0)
1012 	{
1013 		if (ReadFile(h, &u->AdapterInfoList, sizeof(u->AdapterInfoList), &read_size, NULL) == false ||
1014 			u->AdapterInfoList.Signature != SL_SIGNATURE)
1015 		{
1016 			// Signature reception failure
1017 			Debug("Bad Signature.\n");
1018 
1019 			Free(u);
1020 			CloseHandle(h);
1021 
1022 			return NULL;
1023 		}
1024 	}
1025 	else
1026 	{
1027 		while (giveup_tick >= Tick64())
1028 		{
1029 			// Wait until the enumeration is completed
1030 			if (ReadFile(h, &u->AdapterInfoList, sizeof(u->AdapterInfoList), &read_size, NULL) == false ||
1031 				u->AdapterInfoList.Signature != SL_SIGNATURE)
1032 			{
1033 				// Signature reception failure
1034 				Debug("Bad Signature.\n");
1035 
1036 				Free(u);
1037 				CloseHandle(h);
1038 
1039 				return NULL;
1040 			}
1041 
1042 			if (u->AdapterInfoList.EnumCompleted)
1043 			{
1044 				// Complete enumeration
1045 				Debug("Bind Completed! %u\n", u->AdapterInfoList.EnumCompleted);
1046 				break;
1047 			}
1048 
1049 			// Incomplete enumeration
1050 			Debug("Waiting for Bind Complete.\n");
1051 
1052 			SleepThread(25);
1053 		}
1054 	}
1055 
1056 	u->hFile = h;
1057 
1058 	return u;
1059 }
1060 
1061 // Release the driver
SuFree(SU * u)1062 void SuFree(SU *u)
1063 {
1064 	// Validate arguments
1065 	if (u == NULL)
1066 	{
1067 		return;
1068 	}
1069 
1070 	CloseHandle(u->hFile);
1071 
1072 	Free(u);
1073 }
1074 
1075 #endif	// WIN32
1076 
1077