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