1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Mayaqua Kernel
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 // Microsoft.c
103 // For Microsoft Windows code
104 // (not compiled on non-Windows environments)
105
106 #include <GlobalConst.h>
107
108 #ifdef WIN32
109
110 #define MICROSOFT_C
111
112 typedef enum _PNP_VETO_TYPE {
113 PNP_VetoTypeUnknown, // Name is unspecified
114 PNP_VetoLegacyDevice, // Name is an Instance Path
115 PNP_VetoPendingClose, // Name is an Instance Path
116 PNP_VetoWindowsApp, // Name is a Module
117 PNP_VetoWindowsService, // Name is a Service
118 PNP_VetoOutstandingOpen, // Name is an Instance Path
119 PNP_VetoDevice, // Name is an Instance Path
120 PNP_VetoDriver, // Name is a Driver Service Name
121 PNP_VetoIllegalDeviceRequest, // Name is an Instance Path
122 PNP_VetoInsufficientPower, // Name is unspecified
123 PNP_VetoNonDisableable, // Name is an Instance Path
124 PNP_VetoLegacyDriver, // Name is a Service
125 PNP_VetoInsufficientRights // Name is unspecified
126 } PNP_VETO_TYPE, *PPNP_VETO_TYPE;
127
128 #define _WIN32_IE 0x0600
129 #define _WIN32_WINNT 0x0502
130 #define WINVER 0x0502
131 #define SECURITY_WIN32
132 #include <winsock2.h>
133 #include <windows.h>
134 #include <Wintrust.h>
135 #include <Softpub.h>
136 #include <Iphlpapi.h>
137 #include <ws2ipdef.h>
138 #include <netioapi.h>
139 #include <tlhelp32.h>
140 #include <wincon.h>
141 #include <Nb30.h>
142 #include <shlobj.h>
143 #include <commctrl.h>
144 #include <Dbghelp.h>
145 #include <setupapi.h>
146 #include <regstr.h>
147 #include <process.h>
148 #include <psapi.h>
149 #include <wtsapi32.h>
150 #include <Ntsecapi.h>
151 #include <security.h>
152 #include <Msi.h>
153 #include <Msiquery.h>
154 #include <stdio.h>
155 #include <stdlib.h>
156 #include <string.h>
157 #include <wchar.h>
158 #include <stdarg.h>
159 #include <time.h>
160 #include <errno.h>
161 #include <Mayaqua/Mayaqua.h>
162 #include <cfgmgr32.h>
163 #include <sddl.h>
164 #include <Aclapi.h>
165
166 static MS *ms = NULL;
167
168 // Function prototype
169 UINT MsgBox(HWND hWnd, UINT flag, wchar_t *msg);
170 UINT MsgBoxEx(HWND hWnd, UINT flag, wchar_t *msg, ...);
171 void ShowTcpIpConfigUtil(HWND hWnd, bool util_mode);
172 void CmTraffic(HWND hWnd);
173 void CnStart();
174 void InitCedar();
175 void FreeCedar();
176 void InitWinUi(wchar_t *software_name, char *font, UINT fontsize);
177 void FreeWinUi();
178
179 // Global variable
180 UINT64 ms_uint64_1 = 0;
181
182 // Adapter list related
183 static LOCK *lock_adapter_list = NULL;
184 static MS_ADAPTER_LIST *last_adapter_list = NULL;
185
186 // Service related
187 static SERVICE_STATUS_HANDLE ssh = NULL;
188 static SERVICE_STATUS status = { 0 };
189 static HANDLE service_stop_event = NULL;
190 static BOOL (WINAPI *_StartServiceCtrlDispatcher)(CONST LPSERVICE_TABLE_ENTRY) = NULL;
191 static SERVICE_STATUS_HANDLE (WINAPI *_RegisterServiceCtrlHandler)(LPCTSTR, LPHANDLER_FUNCTION) = NULL;
192 static BOOL (WINAPI *_SetServiceStatus)(SERVICE_STATUS_HANDLE, LPSERVICE_STATUS) = NULL;
193 static char g_service_name[MAX_SIZE];
194 static SERVICE_FUNCTION *g_start, *g_stop;
195 static bool exiting = false;
196 static bool wnd_end;
197 static bool is_usermode = false;
198 static bool wts_is_locked_flag = false;
199 static HICON tray_icon;
200 static NOTIFYICONDATA nid;
201 static NOTIFYICONDATAW nid_nt;
202 static bool service_for_9x_mode = false;
203 static THREAD *service_stopper_thread = NULL;
204 static bool tray_inited = false;
205 static HWND hWndUsermode = NULL;
206 static HANDLE hLsa = NULL;
207 static ULONG lsa_package_id = 0;
208 static TOKEN_SOURCE lsa_token_source;
209 static LOCK *vlan_lock = NULL;
210 static COUNTER *suspend_handler_singleton = NULL;
211 static COUNTER *vlan_card_counter = NULL;
212 static volatile BOOL vlan_card_should_stop_flag = false;
213 static volatile BOOL vlan_is_in_suspend_mode = false;
214 static volatile UINT64 vlan_suspend_mode_begin_tick = 0;
215
216 // msi.dll
217 static HINSTANCE hMsi = NULL;
218 static UINT (WINAPI *_MsiGetProductInfoW)(LPCWSTR, LPCWSTR, LPWSTR, LPDWORD) = NULL;
219 static UINT (WINAPI *_MsiConfigureProductW)(LPCWSTR, int, INSTALLSTATE) = NULL;
220 static INSTALLUILEVEL (WINAPI *_MsiSetInternalUI)(INSTALLUILEVEL, HWND *) = NULL;
221 static INSTALLSTATE (WINAPI *_MsiLocateComponentW)(LPCWSTR, LPWSTR, LPDWORD) = NULL;
222
223 #define SE_GROUP_INTEGRITY (0x00000020L)
224
225 typedef enum _TOKEN_INFORMATION_CLASS_VISTA
226 {
227 VistaTokenUser = 1,
228 VistaTokenGroups,
229 VistaTokenPrivileges,
230 VistaTokenOwner,
231 VistaTokenPrimaryGroup,
232 VistaTokenDefaultDacl,
233 VistaTokenSource,
234 VistaTokenType,
235 VistaTokenImpersonationLevel,
236 VistaTokenStatistics,
237 VistaTokenRestrictedSids,
238 VistaTokenSessionId,
239 VistaTokenGroupsAndPrivileges,
240 VistaTokenSessionReference,
241 VistaTokenSandBoxInert,
242 VistaTokenAuditPolicy,
243 VistaTokenOrigin,
244 VistaTokenElevationType,
245 VistaTokenLinkedToken,
246 VistaTokenElevation,
247 VistaTokenHasRestrictions,
248 VistaTokenAccessInformation,
249 VistaTokenVirtualizationAllowed,
250 VistaTokenVirtualizationEnabled,
251 VistaTokenIntegrityLevel,
252 VistaTokenUIAccess,
253 VistaTokenMandatoryPolicy,
254 VistaTokenLogonSid,
255 VistaMaxTokenInfoClass
256 } TOKEN_INFORMATION_CLASS_VISTA, *PTOKEN_INFORMATION_CLASS_VISTA;
257
258 typedef struct MS_MSCHAPV2_PARAMS
259 {
260 wchar_t Username[MAX_SIZE];
261 wchar_t Workstation[MAX_SIZE];
262 wchar_t Domain[MAX_SIZE];
263 UCHAR ClientResponse24[24];
264 UCHAR ResponseBuffer[MAX_SIZE];
265 } MS_MSCHAPV2_PARAMS;
266
267 // The function which should be called once as soon as possible after the process is started
MsInitProcessCallOnce(bool restricted_mode)268 void MsInitProcessCallOnce(bool restricted_mode)
269 {
270 // Mitigate the DLL injection attack
271 char system_dir[MAX_PATH];
272 char kernel32_path[MAX_PATH];
273 UINT len;
274 HINSTANCE hKernel32;
275
276 // Get the full path of kernel32.dll
277 memset(system_dir, 0, sizeof(system_dir));
278 GetSystemDirectory(system_dir, sizeof(system_dir));
279 len = lstrlenA(system_dir);
280 if (system_dir[len] == '\\')
281 {
282 system_dir[len] = 0;
283 }
284 wsprintfA(kernel32_path, "%s\\kernel32.dll", system_dir);
285
286 // Load kernel32.dll
287 hKernel32 = LoadLibraryA(kernel32_path);
288 if (hKernel32 != NULL)
289 {
290 BOOL (WINAPI *_SetDllDirectoryA)(LPCTSTR);
291 BOOL (WINAPI *_SetDllDirectoryW)(LPCWSTR);
292
293 _SetDllDirectoryA = (BOOL (WINAPI *)(LPCTSTR))
294 GetProcAddress(hKernel32, "SetDllDirectoryA");
295
296 _SetDllDirectoryW = (BOOL (WINAPI *)(LPCWSTR))
297 GetProcAddress(hKernel32, "SetDllDirectoryW");
298
299 if (_SetDllDirectoryA != NULL)
300 {
301 _SetDllDirectoryA("");
302 }
303
304 if (_SetDllDirectoryW != NULL)
305 {
306 _SetDllDirectoryW(L"");
307 }
308
309 if (restricted_mode)
310 {
311 BOOL (WINAPI *_SetDefaultDllDirectories)(DWORD) =
312 (BOOL (WINAPI *)(DWORD))
313 GetProcAddress(hKernel32, "SetDefaultDllDirectories");
314
315 if (_SetDefaultDllDirectories != NULL)
316 {
317 _SetDefaultDllDirectories(0x00000800); // LOAD_LIBRARY_SEARCH_SYSTEM32
318 }
319 }
320
321 FreeLibrary(hKernel32);
322 }
323 }
324
325 // Collect the information of the VPN software
MsCollectVpnInfo(BUF * bat,char * tmpdir,char * svc_name,wchar_t * config_name,wchar_t * logdir_name)326 bool MsCollectVpnInfo(BUF *bat, char *tmpdir, char *svc_name, wchar_t *config_name, wchar_t *logdir_name)
327 {
328 wchar_t *inst_dir;
329 char subkey[MAX_PATH];
330 bool ret = false;
331 wchar_t tmpdir_w[MAX_PATH];
332 // Validate arguments
333 if (bat == NULL || tmpdir == NULL || svc_name == NULL || config_name == NULL || logdir_name == NULL)
334 {
335 return false;
336 }
337
338 StrToUni(tmpdir_w, sizeof(tmpdir_w), tmpdir);
339
340 Format(subkey, sizeof(subkey), "SOFTWARE\\" GC_REG_COMPANY_NAME "\\Setup Wizard Settings\\%s", svc_name);
341 inst_dir = MsRegReadStrEx2W(REG_LOCAL_MACHINE, subkey, "InstalledDir", false, true);
342 if (UniIsEmptyStr(inst_dir) == false)
343 {
344 wchar_t config_src[MAX_PATH];
345 wchar_t config_dst[MAX_PATH];
346 wchar_t log_dir[MAX_PATH];
347 DIRLIST *dir;
348 UINT64 max_dt_file = 0;
349
350 // config file
351 CombinePathW(config_src, sizeof(config_src), inst_dir, config_name);
352 UniFormat(config_dst, sizeof(config_dst), L"%s\\%S_%s", tmpdir_w, svc_name, config_name);
353 ret = FileCopyExW(config_src, config_dst, false);
354
355 // Log file
356 CombinePathW(log_dir, sizeof(log_dir), inst_dir, logdir_name);
357
358 dir = EnumDirW(log_dir);
359
360 if (dir != NULL)
361 {
362 UINT i;
363 DIRENT *latest_log = NULL;
364
365 for (i = 0;i < dir->NumFiles;i++)
366 {
367 DIRENT *e = dir->File[i];
368
369 // Get the most recent file
370 if (max_dt_file <= e->UpdateDate)
371 {
372 max_dt_file = e->UpdateDate;
373
374 latest_log = e;
375 }
376 }
377
378 if (latest_log != NULL)
379 {
380 wchar_t fullpath[MAX_SIZE];
381 IO *f;
382
383 // Open the log file
384 CombinePathW(fullpath, sizeof(fullpath), log_dir, latest_log->FileNameW);
385 f = FileOpenExW(fullpath, false, false);
386
387 if (f != NULL)
388 {
389 UINT size = FileSize(f);
390
391 if (size >= 1)
392 {
393 UINT copy_size = 1024 * 1024;
394 UINT seek_size = 0;
395 UCHAR *buf;
396
397 if (copy_size < size)
398 {
399 seek_size = size - copy_size;
400 }
401 else
402 {
403 copy_size = size;
404 }
405
406 FileSeek(f, 0, seek_size);
407
408 buf = Malloc(copy_size + 3);
409 buf[0] = 0xEF;
410 buf[1] = 0xBB;
411 buf[2] = 0xBF;
412 if (FileRead(f, buf + 3, copy_size))
413 {
414 char log_dst_filename[MAX_PATH];
415
416 Format(log_dst_filename, sizeof(log_dst_filename), "%s\\lastlog_%s_%s",
417 tmpdir, svc_name, latest_log->FileName);
418
419 SaveFile(log_dst_filename, buf, copy_size + 3);
420 }
421
422 Free(buf);
423 }
424
425 FileClose(f);
426 }
427 }
428
429 FreeDir(dir);
430 }
431 }
432 Free(inst_dir);
433
434 return ret;
435 }
436
437 // Save the system information
MsSaveSystemInfo(wchar_t * dst_filename)438 bool MsSaveSystemInfo(wchar_t *dst_filename)
439 {
440 char tmpdir[MAX_PATH];
441 UCHAR rand_data[SHA1_SIZE];
442 char rand_str[MAX_SIZE];
443 char filename_bat[MAX_PATH];
444 BUF *bat;
445 char tmp[MAX_PATH];
446 char cmd[MAX_PATH];
447 char cmd_arg[MAX_PATH];
448 bool ret = false;
449 DIRLIST *dir;
450 UINT i;
451 // Validate arguments
452 if (dst_filename == NULL)
453 {
454 return false;
455 }
456 if (MsIsAdmin() == false || MsIsWin2000OrGreater() == false)
457 {
458 return false;
459 }
460
461 Rand(rand_data, sizeof(rand_data));
462 BinToStr(rand_str, sizeof(rand_str), rand_data, 4);
463
464 // Create a temporary directory
465 Format(tmpdir, sizeof(tmpdir), "%s\\Temp\\se_support_%s", MsGetWindowsDir(), rand_str);
466 MakeDirEx(tmpdir);
467
468 // Create a batch file
469 CombinePath(filename_bat, sizeof(filename_bat), tmpdir, "make_system_info.cmd");
470 bat = NewBuf();
471
472 Format(tmp, sizeof(tmp), "systeminfo > %s\\SystemInfo.txt", tmpdir);
473 WriteBufLine(bat, tmp);
474
475 Format(tmp, sizeof(tmp), "ipconfig > %s\\ipconfig.txt", tmpdir);
476 WriteBufLine(bat, tmp);
477
478 Format(tmp, sizeof(tmp), "netsh dump > %s\\netsh.txt", tmpdir);
479 WriteBufLine(bat, tmp);
480
481 Format(tmp, sizeof(tmp), "route print > %s\\route.txt", tmpdir);
482 WriteBufLine(bat, tmp);
483
484 Format(tmp, sizeof(tmp), "netstat -nab > %s\\netstat_nab.txt", tmpdir);
485 WriteBufLine(bat, tmp);
486
487 Format(tmp, sizeof(tmp), "netstat -nao > %s\\netstat_nao.txt", tmpdir);
488 WriteBufLine(bat, tmp);
489
490 Format(tmp, sizeof(tmp), "netstat -na > %s\\netstat_na.txt", tmpdir);
491 WriteBufLine(bat, tmp);
492
493 Format(tmp, sizeof(tmp), "netstat -fab > %s\\netstat_fab.txt", tmpdir);
494 WriteBufLine(bat, tmp);
495
496 Format(tmp, sizeof(tmp), "netstat -fao > %s\\netstat_fao.txt", tmpdir);
497 WriteBufLine(bat, tmp);
498
499 Format(tmp, sizeof(tmp), "netstat -fa > %s\\netstat_fa.txt", tmpdir);
500 WriteBufLine(bat, tmp);
501
502 Format(tmp, sizeof(tmp), "netstat -ab > %s\\netstat_ab.txt", tmpdir);
503 WriteBufLine(bat, tmp);
504
505 Format(tmp, sizeof(tmp), "netstat -ao > %s\\netstat_ao.txt", tmpdir);
506 WriteBufLine(bat, tmp);
507
508 Format(tmp, sizeof(tmp), "netstat -a > %s\\netstat_a.txt", tmpdir);
509 WriteBufLine(bat, tmp);
510
511 Format(tmp, sizeof(tmp), "\"%s\\Common Files\\Microsoft Shared\\MSInfo\\msinfo32.exe\" /report %s\\SystemInfo.txt", MsGetProgramFilesDir(), tmpdir);
512 WriteBufLine(bat, tmp);
513
514 // Collect the information of the VPN software
515 MsCollectVpnInfo(bat, tmpdir, "vpnclient", L"vpn_client.config", L"client_log");
516 MsCollectVpnInfo(bat, tmpdir, "vpnserver", L"vpn_server.config", L"server_log");
517 MsCollectVpnInfo(bat, tmpdir, "vpnbridge", L"vpn_bridge.config", L"server_log");
518
519 MsCollectVpnInfo(bat, tmpdir, "sevpnclient", L"vpn_client.config", L"client_log");
520 MsCollectVpnInfo(bat, tmpdir, "sevpnserver", L"vpn_server.config", L"server_log");
521 MsCollectVpnInfo(bat, tmpdir, "sevpnbridge", L"vpn_bridge.config", L"server_log");
522
523 WriteBufLine(bat, "");
524
525 DumpBuf(bat, filename_bat);
526
527 FreeBuf(bat);
528
529 // Run the batch file
530 CombinePath(cmd, sizeof(cmd), MsGetSystem32Dir(), "cmd.exe");
531 Format(cmd_arg, sizeof(cmd_arg), "/C %s", filename_bat);
532 if (Win32Run(cmd, cmd_arg, false, true))
533 {
534 dir = EnumDir(tmpdir);
535 if (dir != NULL)
536 {
537 ZIP_PACKER *zip;
538 zip = NewZipPacker();
539
540 for (i = 0;i < dir->NumFiles;i++)
541 {
542 char *name = dir->File[i]->FileName;
543 char full[MAX_PATH];
544
545 CombinePath(full, sizeof(full), tmpdir, name);
546
547 ZipAddRealFile(zip, name, SystemTime64(), 0, full);
548 }
549 FreeDir(dir);
550
551 ret = ZipWriteW(zip, dst_filename);
552 FreeZipPacker(zip);
553 }
554 }
555
556 // Delete the temporary directory
557 dir = EnumDir(tmpdir);
558 if (dir != NULL)
559 {
560 for (i = 0;i < dir->NumFiles;i++)
561 {
562 char *name = dir->File[i]->FileName;
563 char full[MAX_PATH];
564
565 CombinePath(full, sizeof(full), tmpdir, name);
566
567 if (EndWith(full, ".txt") || EndWith(full, ".cmd") || EndWith(full, ".config") || EndWith(full, ".log"))
568 {
569 FileDelete(full);
570 }
571 }
572 FreeDir(dir);
573 }
574 DeleteDir(tmpdir);
575
576 return ret;
577 }
578
579 // Determine whether this is running in a VM
MsIsInVmMain()580 bool MsIsInVmMain()
581 {
582 char *bat_data = "On Error Resume Next\r\n\r\nDim str\r\n\r\nSet wmi_svc = GetObject(\"winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2\")\r\n\r\nSet items = wmi_svc.ExecQuery(\"Select * from Win32_BaseBoard\")\r\n\r\nFor Each item in items\r\n str = str & item.Manufacturer\r\nNext\r\n\r\nSet items = Nothing\r\n\r\nSet items = wmi_svc.ExecQuery(\"Select * from Win32_ComputerSystem\")\r\n\r\nFor Each item in items\r\n str = str & item.Manufacturer\r\nNext\r\n\r\nSet items = Nothing\r\n\r\nSet wmi_svc = Nothing\r\n\r\nstr = LCase(str)\r\n\r\nDim ret\r\n\r\nret = 0\r\n\r\nif InStr(str, \"microsoft corporation\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"vmware\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"virtualbox\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"virtualpc\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"xen\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"hvm\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"domu\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"kvm\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"oracle vm\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"qemu\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"parallels\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"xvm\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"virtual\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nif InStr(str, \"bochs\") > 0 then\r\n ret = 1\r\nend if\r\n\r\nwscript.quit ret\r\n\r\n";
583 wchar_t bat_filename[MAX_SIZE];
584 wchar_t cscript_exe[MAX_SIZE];
585 wchar_t tmp[MAX_SIZE];
586 void *process;
587 bool ret = false;
588
589 if (MsIsNt() == false)
590 {
591 return false;
592 }
593
594 if (MsIsWin2000OrGreater() == false)
595 {
596 return false;
597 }
598
599 CombinePathW(bat_filename, sizeof(bat_filename), MsGetMyTempDirW(), L"detectvm.vbs");
600
601 if (DumpDataW(bat_data, StrLen(bat_data), bat_filename) == false)
602 {
603 return false;
604 }
605
606 CombinePathW(cscript_exe, sizeof(cscript_exe), MsGetSystem32DirW(), L"cscript.exe");
607
608 UniFormat(tmp, sizeof(tmp), L"\"%s\"", bat_filename);
609
610 process = Win32RunEx3W(cscript_exe, tmp, true, NULL, true);
611
612 if (process == NULL)
613 {
614 return false;
615 }
616
617 if (Win32WaitProcess(process, 30000))
618 {
619 DWORD exit_code = 0;
620
621 if (GetExitCodeProcess(process, &exit_code))
622 {
623 if (exit_code == 1)
624 {
625 ret = true;
626 }
627 }
628 }
629
630 Win32CloseProcess(process);
631
632 return ret;
633 }
MsIsInVm()634 bool MsIsInVm()
635 {
636 static bool flag_detected = false;
637 static bool flag_is_vm = false;
638
639 if (flag_detected == false)
640 {
641 flag_is_vm = MsIsInVmMain();
642
643 flag_detected = true;
644 }
645
646 return flag_is_vm;
647 }
648
649 // Get the current module handle
MsGetCurrentModuleHandle()650 void *MsGetCurrentModuleHandle()
651 {
652 return ms->hInst;
653 }
654
655 // Resource enumeration procedure
MsEnumResourcesInternalProc(HMODULE hModule,const char * type,char * name,LONG_PTR lParam)656 bool CALLBACK MsEnumResourcesInternalProc(HMODULE hModule, const char *type, char *name, LONG_PTR lParam)
657 {
658 LIST *o = (LIST *)lParam;
659 // Validate arguments
660 if (type == NULL || name == NULL || o == NULL)
661 {
662 return true;
663 }
664
665 Add(o, CopyStr(name));
666
667 return true;
668 }
669
670 // Enumeration of resources
MsEnumResources(void * hModule,char * type)671 TOKEN_LIST *MsEnumResources(void *hModule, char *type)
672 {
673 LIST *o;
674 TOKEN_LIST *ret;
675 // Validate arguments
676 if (hModule == NULL)
677 {
678 hModule = MsGetCurrentModuleHandle();
679 }
680 if (type == NULL)
681 {
682 return NullToken();
683 }
684
685 o = NewListFast(NULL);
686
687 if (EnumResourceNamesA(hModule, type, MsEnumResourcesInternalProc, (LONG_PTR)o) == false)
688 {
689 ReleaseList(o);
690 return NullToken();
691 }
692
693 ret = ListToTokenList(o);
694
695 FreeStrList(o);
696
697 return ret;
698 }
699
700 // Get whether the locale ID of the current user is Japanese
MsIsCurrentUserLocaleIdJapanese()701 bool MsIsCurrentUserLocaleIdJapanese()
702 {
703 UINT lcid = MsGetUserLocaleId();
704
705 if (lcid == 1041)
706 {
707 return true;
708 }
709
710 return false;
711 }
712
713 // Get the locale ID of the user
MsGetUserLocaleId()714 UINT MsGetUserLocaleId()
715 {
716 static UINT lcid_cache = 0;
717
718 if (lcid_cache == 0)
719 {
720 lcid_cache = (UINT)GetUserDefaultLCID();
721 }
722
723 return lcid_cache;
724 }
725
726 // Get the locale ID of the system
MsGetSystemLocaleId()727 UINT MsGetSystemLocaleId()
728 {
729 static UINT lcid_cache = 0;
730
731 if (lcid_cache == 0)
732 {
733 lcid_cache = (UINT)GetSystemDefaultLCID();
734 }
735
736 return lcid_cache;
737 }
738
739 // Set a secure ACL to the specified file or directory
MsSetFileSecureAcl(wchar_t * path)740 bool MsSetFileSecureAcl(wchar_t *path)
741 {
742 SID *sid_system;
743 SID *sid_admin;
744 bool ret = false;
745 // Validate arguments
746 if (path == NULL)
747 {
748 return false;
749 }
750 if (ms->nt == NULL)
751 {
752 return false;
753 }
754 if (ms->nt->SetNamedSecurityInfoW == NULL || ms->nt->AddAccessAllowedAceEx == NULL)
755 {
756 return false;
757 }
758
759 sid_system = MsGetSidFromAccountName("SYSTEM");
760 sid_admin = MsGetSidFromAccountName("Administrators");
761
762 if (sid_system != NULL && sid_admin != NULL)
763 {
764 UINT acl_size = 4096;
765 ACL *acl;
766
767 acl = ZeroMalloc(acl_size);
768
769 if (InitializeAcl(acl, acl_size, 2))
770 {
771 if (ms->nt->AddAccessAllowedAceEx(acl, 2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, GENERIC_ALL, sid_system) &&
772 ms->nt->AddAccessAllowedAceEx(acl, 2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, GENERIC_ALL, sid_admin))
773 {
774 if (ms->nt->SetNamedSecurityInfoW(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, acl, NULL) == ERROR_SUCCESS)
775 {
776 ret = true;
777 }
778 }
779 }
780
781 Free(acl);
782 }
783
784 MsFreeSid(sid_system);
785 MsFreeSid(sid_admin);
786
787 return ret;
788 }
789
790 // Disable the minimization function of the number of network connections by WCM
MsDisableWcmNetworkMinimize()791 void MsDisableWcmNetworkMinimize()
792 {
793 MS_WCM_POLICY_VALUE v;
794 bool b;
795 if (ms->nt == NULL)
796 {
797 return;
798 }
799 if (ms->nt->WcmQueryProperty == NULL || ms->nt->WcmSetProperty == NULL || ms->nt->WcmFreeMemory == NULL || ms->nt->WcmGetProfileList == NULL)
800 {
801 return;
802 }
803
804 if (MsIsWindows8() == false)
805 {
806 return;
807 }
808
809 Zero(&v, sizeof(v));
810 v.fIsGroupPolicy = true;
811 v.fValue = false;
812 b = false;
813 ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_minimize_policy, NULL, sizeof(v), (const BYTE *)&v);
814 ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_minimize_policy, NULL, sizeof(b), (const BYTE *)&b);
815
816 Zero(&v, sizeof(v));
817 v.fIsGroupPolicy = true;
818 v.fValue = false;
819 b = false;
820 ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_domain_policy, NULL, sizeof(v), (const BYTE *)&v);
821 ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_domain_policy, NULL, sizeof(b), (const BYTE *)&b);
822
823 Zero(&v, sizeof(v));
824 v.fIsGroupPolicy = false;
825 v.fValue = false;
826 ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_minimize_policy, NULL, sizeof(v), (const BYTE *)&v);
827 ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_minimize_policy, NULL, sizeof(b), (const BYTE *)&b);
828
829 Zero(&v, sizeof(v));
830 v.fIsGroupPolicy = false;
831 v.fValue = false;
832 ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_domain_policy, NULL, sizeof(v), (const BYTE *)&v);
833 ms->nt->WcmSetProperty(NULL, NULL, ms_wcm_global_property_domain_policy, NULL, sizeof(b), (const BYTE *)&b);
834 }
835
836 // Request the MS-CHAPv2 authentication to the LSA
MsPerformMsChapV2AuthByLsa(char * username,UCHAR * challenge8,UCHAR * client_response_24,UCHAR * ret_pw_hash_hash)837 bool MsPerformMsChapV2AuthByLsa(char *username, UCHAR *challenge8, UCHAR *client_response_24, UCHAR *ret_pw_hash_hash)
838 {
839 bool ret = false;
840 char user[MAX_SIZE];
841 char domain[MAX_SIZE];
842 wchar_t workstation[MAX_SIZE + 1];
843 LSA_STRING origin;
844 MSV1_0_LM20_LOGON *m;
845 MS_MSCHAPV2_PARAMS *p;
846 UINT m_size;
847 DWORD sz;
848 void *profile_buffer = NULL;
849 LUID logon_id;
850 UINT profile_buffer_size = 0;
851 UINT i;
852 HANDLE hLogon = NULL;
853 QUOTA_LIMITS q;
854 char *origin_str = "SE-VPN";
855 NTSTATUS sub_status = 0;
856 // Validate arguments
857 if (username == NULL || challenge8 == NULL || client_response_24 == NULL || ret_pw_hash_hash == NULL)
858 {
859 return false;
860 }
861 if (hLsa == NULL)
862 {
863 return false;
864 }
865
866 ParseNtUsername(username, user, sizeof(user), domain, sizeof(domain), false);
867
868 // Get the machine name
869 Zero(workstation, sizeof(workstation));
870 sz = MAX_SIZE;
871 GetComputerNameW(workstation, &sz);
872
873 // Build a MSV1_0_INTERACTIVE_LOGON
874 m_size = sizeof(MSV1_0_LM20_LOGON) + sizeof(MS_MSCHAPV2_PARAMS);
875 m = ZeroMalloc(m_size);
876 p = (MS_MSCHAPV2_PARAMS *)(((UCHAR *)m) + sizeof(MSV1_0_LM20_LOGON));
877
878 StrToUni(p->Username, sizeof(p->Username), user);
879 StrToUni(p->Domain, sizeof(p->Domain), domain);
880 UniStrCpy(p->Workstation, sizeof(p->Workstation), workstation);
881 Copy(p->ClientResponse24, client_response_24, 24);
882
883 m->MessageType = MsV1_0Lm20Logon;
884
885 // User name
886 m->UserName.Length = m->UserName.MaximumLength = (USHORT)(UniStrLen(p->Username) * sizeof(wchar_t));
887 m->UserName.Buffer = p->Username;
888
889 // Workstation name
890 m->Workstation.Length = m->Workstation.MaximumLength = (USHORT)(UniStrLen(p->Workstation) * sizeof(wchar_t));
891 m->Workstation.Buffer = p->Workstation;
892
893 // Domain name
894 if (IsEmptyUniStr(p->Domain) == false)
895 {
896 m->LogonDomainName.Length = m->LogonDomainName.MaximumLength = (USHORT)(UniStrLen(p->Domain) * sizeof(wchar_t));
897 m->LogonDomainName.Buffer = p->Domain;
898 }
899
900 // Challenge
901 Copy(m->ChallengeToClient, challenge8, 8);
902
903 // Response
904 m->CaseInsensitiveChallengeResponse.Length = m->CaseInsensitiveChallengeResponse.MaximumLength = 24;
905 m->CaseInsensitiveChallengeResponse.Buffer = p->ClientResponse24;
906
907 m->CaseSensitiveChallengeResponse.Length = m->CaseSensitiveChallengeResponse.MaximumLength = sizeof(p->ResponseBuffer);
908 m->CaseSensitiveChallengeResponse.Buffer = p->ResponseBuffer;
909
910 m->ParameterControl = MSV1_0_ALLOW_MSVCHAPV2;
911
912 Zero(&origin, sizeof(origin));
913 origin.Length = origin.MaximumLength = StrLen(origin_str);
914 origin.Buffer = origin_str;
915
916 Zero(&logon_id, sizeof(logon_id));
917 Zero(&q, sizeof(q));
918
919 i = ms->nt->LsaLogonUser(hLsa, &origin, Network, lsa_package_id, m, m_size, NULL, &lsa_token_source,
920 &profile_buffer, &profile_buffer_size, &logon_id, &hLogon, &q, &sub_status);
921
922 if (i == 0)
923 {
924 if (profile_buffer != NULL)
925 {
926 MSV1_0_LM20_LOGON_PROFILE *response = (MSV1_0_LM20_LOGON_PROFILE *)profile_buffer;
927
928 Copy(ret_pw_hash_hash, response->UserSessionKey, 16);
929
930 ret = true;
931
932 ms->nt->LsaFreeReturnBuffer(profile_buffer);
933 }
934 CloseHandle(hLogon);
935 }
936
937 Free(m);
938
939 return ret;
940 }
941
942 // Send a pulse
MsSendGlobalPulse(void * p)943 void MsSendGlobalPulse(void *p)
944 {
945 HANDLE h;
946 // Validate arguments
947 if (p == NULL)
948 {
949 return;
950 }
951
952 h = (HANDLE)p;
953
954 PulseEvent(h);
955 }
956
957 // Release a pulse
MsCloseGlobalPulse(void * p)958 void MsCloseGlobalPulse(void *p)
959 {
960 HANDLE h;
961 // Validate arguments
962 if (p == NULL)
963 {
964 return;
965 }
966
967 h = (HANDLE)p;
968
969 CloseHandle(h);
970 }
971
972 // Wait for arriving the pulse
MsWaitForGlobalPulse(void * p,UINT timeout)973 bool MsWaitForGlobalPulse(void *p, UINT timeout)
974 {
975 HANDLE h;
976 UINT ret;
977 // Validate arguments
978 if (p == NULL)
979 {
980 return false;
981 }
982 if (timeout == TIMEOUT_INFINITE)
983 {
984 timeout = INFINITE;
985 }
986
987 h = (HANDLE)p;
988
989 ret = WaitForSingleObject(h, timeout);
990
991 if (ret == WAIT_OBJECT_0)
992 {
993 return true;
994 }
995
996 return false;
997 }
998
999 // Open or create a pulse
MsOpenOrCreateGlobalPulse(char * name)1000 void *MsOpenOrCreateGlobalPulse(char *name)
1001 {
1002 UCHAR hash[20];
1003 char tmp[MAX_SIZE];
1004 char tmp2[MAX_SIZE];
1005 HANDLE h;
1006 // Validate arguments
1007 if (name == NULL)
1008 {
1009 return NULL;
1010 }
1011
1012 StrCpy(tmp, sizeof(tmp), name);
1013 Trim(tmp);
1014 StrUpper(tmp);
1015
1016 HashSha1(hash, name, StrLen(name));
1017
1018 BinToStr(tmp, sizeof(tmp), hash, sizeof(hash));
1019
1020 Format(tmp2, sizeof(tmp2), "GlobalPulse_%s", tmp);
1021
1022 if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType))
1023 {
1024 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2 ||
1025 GetOsInfo()->OsType == OSTYPE_WINDOWS_NT_4_TERMINAL_SERVER)
1026 {
1027 Format(tmp2, sizeof(tmp2), "Global\\GlobalPulse_%s", tmp);
1028 }
1029 }
1030
1031 h = CreateEvent(NULL, true, false, tmp2);
1032
1033 return (void *)h;
1034 }
1035
1036 // Stop the IPsec service
MsStopIPsecService()1037 bool MsStopIPsecService()
1038 {
1039 if (MsIsServiceRunning(MsGetIPsecServiceName()))
1040 {
1041 Debug("Stopping Windows Service: %s\n", MsGetIPsecServiceName());
1042 if (MsStopService(MsGetIPsecServiceName()))
1043 {
1044 return true;
1045 }
1046 }
1047
1048 return false;
1049 }
1050
1051 // Start the IPsec service
MsStartIPsecService()1052 bool MsStartIPsecService()
1053 {
1054 if (MsIsServiceRunning(MsGetIPsecServiceName()) == false)
1055 {
1056 Debug("Starting Windows Service: %s\n", MsGetIPsecServiceName());
1057 return MsStartService(MsGetIPsecServiceName());
1058 }
1059
1060 return false;
1061 }
1062
1063 // Get the IPsec service name
MsGetIPsecServiceName()1064 char *MsGetIPsecServiceName()
1065 {
1066 char *svc_name = "PolicyAgent";
1067
1068 if (MsIsVista())
1069 {
1070 svc_name = "ikeext";
1071 }
1072
1073 return svc_name;
1074 }
1075
1076 // Initialize the global lock
MsInitGlobalLock(char * name,bool ts_local)1077 void *MsInitGlobalLock(char *name, bool ts_local)
1078 {
1079 char tmp[MAX_SIZE];
1080 HANDLE h;
1081 // Validate arguments
1082 if (name == NULL)
1083 {
1084 name = "default_global_lock";
1085 }
1086
1087 if (ts_local)
1088 {
1089 HashInstanceNameLocal(tmp, sizeof(tmp), name);
1090 }
1091 else
1092 {
1093 HashInstanceName(tmp, sizeof(tmp), name);
1094 }
1095
1096 h = CreateMutexA(NULL, false, tmp);
1097 if (h == NULL || h == INVALID_HANDLE_VALUE)
1098 {
1099 return NULL;
1100 }
1101
1102 return (void *)h;
1103 }
1104
1105 // Get a global lock
MsGlobalLock(void * p)1106 void MsGlobalLock(void *p)
1107 {
1108 HANDLE h = (HANDLE)p;
1109 // Validate arguments
1110 if (h == NULL)
1111 {
1112 return;
1113 }
1114
1115 WaitForSingleObject(p, INFINITE);
1116 }
1117
1118 // Unlock the global lock
MsGlobalUnlock(void * p)1119 void MsGlobalUnlock(void *p)
1120 {
1121 HANDLE h = (HANDLE)p;
1122 // Validate arguments
1123 if (h == NULL)
1124 {
1125 return;
1126 }
1127
1128 ReleaseMutex(h);
1129 }
1130
1131 // Release the global lock
MsFreeGlobalLock(void * p)1132 void MsFreeGlobalLock(void *p)
1133 {
1134 HANDLE h = (HANDLE)p;
1135 // Validate arguments
1136 if (h == NULL)
1137 {
1138 return;
1139 }
1140
1141 CloseHandle(h);
1142 }
1143
1144
1145 // Set the mode not to show the errors
MsSetErrorModeToSilent()1146 void MsSetErrorModeToSilent()
1147 {
1148 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
1149 }
1150
1151 // Get the file information
MsGetFileInformation(void * h,void * info)1152 bool MsGetFileInformation(void *h, void *info)
1153 {
1154 // Validate arguments
1155 if (h == INVALID_HANDLE_VALUE || info == NULL)
1156 {
1157 return false;
1158 }
1159
1160 if (MsIsNt() == false)
1161 {
1162 return false;
1163 }
1164
1165 if (ms->nt->GetFileInformationByHandle == NULL)
1166 {
1167 return false;
1168 }
1169
1170 return ms->nt->GetFileInformationByHandle(h, info);
1171 }
1172
1173 // Set the shutdown parameters of the process
MsSetShutdownParameters(UINT level,UINT flag)1174 void MsSetShutdownParameters(UINT level, UINT flag)
1175 {
1176 if (MsIsNt() == false)
1177 {
1178 return;
1179 }
1180
1181 if (ms->nt == false || ms->nt->SetProcessShutdownParameters == NULL)
1182 {
1183 return;
1184 }
1185
1186 ms->nt->SetProcessShutdownParameters(level, flag);
1187 }
1188
1189 // Get whether the version of the OS is Windows XP or Windows Vista or later
MsIsWinXPOrWinVista()1190 bool MsIsWinXPOrWinVista()
1191 {
1192 OS_INFO *info = GetOsInfo();
1193 if (info == NULL)
1194 {
1195 return false;
1196 }
1197
1198 if (OS_IS_WINDOWS_NT(info->OsType) == false)
1199 {
1200 return false;
1201 }
1202
1203 if (GET_KETA(info->OsType, 100) >= 3)
1204 {
1205 return true;
1206 }
1207
1208 return false;
1209 }
1210
1211 // Write to the event log
MsWriteEventLog(void * p,UINT type,wchar_t * str)1212 bool MsWriteEventLog(void *p, UINT type, wchar_t *str)
1213 {
1214 MS_EVENTLOG *g = (MS_EVENTLOG *)p;
1215 wchar_t *strings[2];
1216 UINT id = 0;
1217 UINT typeapi = 0;
1218 // Validate arguments
1219 if (g == NULL || type >= 5 || str == NULL)
1220 {
1221 return false;
1222 }
1223
1224 strings[0] = str;
1225
1226 switch (type)
1227 {
1228 case MS_EVENTLOG_TYPE_INFORMATION:
1229 id = MS_RC_EVENTLOG_TYPE_INFORMATION;
1230 typeapi = EVENTLOG_INFORMATION_TYPE;
1231 break;
1232
1233 case MS_EVENTLOG_TYPE_WARNING:
1234 id = MS_RC_EVENTLOG_TYPE_WARNING;
1235 typeapi = EVENTLOG_WARNING_TYPE;
1236 break;
1237
1238 case MS_EVENTLOG_TYPE_ERROR:
1239 id = MS_RC_EVENTLOG_TYPE_ERROR;
1240 typeapi = EVENTLOG_ERROR_TYPE;
1241 break;
1242 }
1243
1244 return ms->nt->ReportEventW(g->hEventLog, typeapi, 0, id, NULL, 1, 0, strings, NULL);
1245 }
1246
1247 // Release of the event log
MsFreeEventLog(void * p)1248 void MsFreeEventLog(void *p)
1249 {
1250 MS_EVENTLOG *g = (MS_EVENTLOG *)p;
1251 // Validate arguments
1252 if (g == NULL)
1253 {
1254 return;
1255 }
1256
1257 ms->nt->DeregisterEventSource(g->hEventLog);
1258
1259 Free(g);
1260 }
1261
1262 // Initialization of the event log
MsInitEventLog(wchar_t * src_name)1263 void *MsInitEventLog(wchar_t *src_name)
1264 {
1265 MS_EVENTLOG *g;
1266 HANDLE h;
1267 wchar_t keyname[MAX_PATH];
1268 char keyname_a[MAX_PATH];
1269 wchar_t *exename;
1270 // Validate arguments
1271 if (src_name == NULL)
1272 {
1273 return NULL;
1274 }
1275
1276 // Write the key to the registry
1277 exename = MsGetExeFileNameW();
1278 UniFormat(keyname, sizeof(keyname),
1279 L"SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\%s",
1280 src_name);
1281 UniToStr(keyname_a, sizeof(keyname_a), keyname);
1282
1283 MsRegWriteStrExpandExW(REG_LOCAL_MACHINE, keyname_a, "EventMessageFile",
1284 exename, false);
1285
1286 MsRegWriteIntEx(REG_LOCAL_MACHINE, keyname_a, "TypesSupported", 7, false);
1287
1288 h = ms->nt->RegisterEventSourceW(NULL, src_name);
1289 if (h == NULL)
1290 {
1291 return NULL;
1292 }
1293
1294 g = ZeroMalloc(sizeof(MS_EVENTLOG));
1295
1296 g->hEventLog = h;
1297
1298 return (void *)g;
1299 }
1300
1301 // Empty the clipboard
MsDeleteClipboard()1302 void MsDeleteClipboard()
1303 {
1304 OpenClipboard(NULL);
1305
1306 EmptyClipboard();
1307
1308 CloseClipboard();
1309 }
1310
1311 // Get the process ID of the clipboard owner
MsGetClipboardOwnerProcessId()1312 UINT MsGetClipboardOwnerProcessId()
1313 {
1314 HWND hWnd = GetClipboardOwner();
1315 DWORD pid = 0;
1316
1317 if (hWnd == NULL)
1318 {
1319 return 0;
1320 }
1321
1322 GetWindowThreadProcessId(hWnd, &pid);
1323
1324 return pid;
1325 }
1326
1327 // Restart of MMCSS
MsRestartMMCSS()1328 void MsRestartMMCSS()
1329 {
1330 MsStopService("CTAudSvcService");
1331 MsStopService("audiosrv");
1332 MsStopService("MMCSS");
1333 MsStartService("MMCSS");
1334 MsStartService("audiosrv");
1335 MsStartService("CTAudSvcService");
1336 }
1337
1338 // Enable / disable network throttling by MMCSS
MsSetMMCSSNetworkThrottlingEnable(bool enable)1339 void MsSetMMCSSNetworkThrottlingEnable(bool enable)
1340 {
1341 UINT value;
1342 if (MsIsVista() == false)
1343 {
1344 return;
1345 }
1346
1347 if (enable)
1348 {
1349 value = 0x0000000a;
1350 }
1351 else
1352 {
1353 value = 0xffffffff;
1354 }
1355
1356 MsRegWriteIntEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME, "NetworkThrottlingIndex",
1357 value,
1358 false, true);
1359
1360 MsRestartMMCSS();
1361 }
1362
1363 // Examine whether the Network throttling by MMCSS is enabled
MsIsMMCSSNetworkThrottlingEnabled()1364 bool MsIsMMCSSNetworkThrottlingEnabled()
1365 {
1366 UINT value;
1367 if (MsIsVista() == false)
1368 {
1369 return false;
1370 }
1371
1372 if (MsRegIsKeyEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME, false, true) == false)
1373 {
1374 return false;
1375 }
1376
1377 value = MsRegReadIntEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME,
1378 "NetworkThrottlingIndex", false, true);
1379
1380 if (value == 0)
1381 {
1382 return false;
1383 }
1384
1385 if (value == 0x0000000a)
1386 {
1387 return true;
1388 }
1389
1390 return false;
1391 }
1392
1393 // Delete all the subkeys
MsRegDeleteSubkeys(UINT root,char * keyname,bool force32bit,bool force64bit)1394 void MsRegDeleteSubkeys(UINT root, char *keyname, bool force32bit, bool force64bit)
1395 {
1396 TOKEN_LIST *t;
1397 UINT i;
1398 // Validate arguments
1399 if (keyname == NULL)
1400 {
1401 return;
1402 }
1403
1404 t = MsRegEnumKeyEx2(root, keyname, force32bit, force64bit);
1405 if (t == NULL)
1406 {
1407 return;
1408 }
1409
1410 for (i = 0;i < t->NumTokens;i++)
1411 {
1412 char tmp[MAX_PATH];
1413
1414 Format(tmp, sizeof(tmp), "%s\\%s", keyname, t->Token[i]);
1415
1416 MsRegDeleteKeyEx2(root, tmp, force32bit, force64bit);
1417 }
1418
1419 FreeToken(t);
1420 }
1421
1422 // Convert the data in the buffer to the subkey of the registry
MsBufToRegSubkeys(UINT root,char * keyname,BUF * b,bool overwrite,bool force32bit,bool force64bit)1423 void MsBufToRegSubkeys(UINT root, char *keyname, BUF *b, bool overwrite, bool force32bit, bool force64bit)
1424 {
1425 UINT i;
1426 UINT a;
1427 UINT num_keys;
1428 // Validate arguments
1429 if (keyname == NULL || b == NULL)
1430 {
1431 return;
1432 }
1433
1434 SeekBuf(b, 0, 0);
1435
1436 num_keys = ReadBufInt(b);
1437
1438 for (i = 0;i < num_keys;i++)
1439 {
1440 char subkeyname[MAX_PATH];
1441 char fullkeyname[MAX_PATH];
1442 UINT j;
1443 UINT num_values;
1444
1445 Zero(subkeyname, sizeof(subkeyname));
1446 ReadBufStr(b, subkeyname, sizeof(subkeyname));
1447
1448 Format(fullkeyname, sizeof(fullkeyname), "%s\\%s", keyname, subkeyname);
1449
1450 num_values = ReadBufInt(b);
1451
1452 for (j = 0;j < num_values;j++)
1453 {
1454 char valuename[MAX_PATH];
1455 char data[MAX_SIZE];
1456
1457 Zero(valuename, sizeof(valuename));
1458 ReadBufStr(b, valuename, sizeof(valuename));
1459
1460 a = ReadBufInt(b);
1461
1462 if (a == 0)
1463 {
1464 Zero(data, sizeof(data));
1465 ReadBufStr(b, data, sizeof(data));
1466
1467 if (overwrite || MsRegIsValueEx2(root, fullkeyname, valuename, force32bit, force64bit) == false)
1468 {
1469 MsRegWriteStrEx2(root, fullkeyname, valuename, data, force32bit, force64bit);
1470 }
1471 }
1472 else
1473 {
1474 if (overwrite || MsRegIsValueEx2(root, fullkeyname, valuename, force32bit, force64bit) == false)
1475 {
1476 MsRegWriteIntEx2(root, fullkeyname, valuename, ReadBufInt(b), force32bit, force64bit);
1477 }
1478 }
1479 }
1480 }
1481 }
1482
1483 // Convert data in the registry subkey to the buffer
MsRegSubkeysToBuf(UINT root,char * keyname,bool force32bit,bool force64bit)1484 BUF *MsRegSubkeysToBuf(UINT root, char *keyname, bool force32bit, bool force64bit)
1485 {
1486 TOKEN_LIST *t;
1487 UINT i;
1488 BUF *b;
1489 // Validate arguments
1490 if (keyname == NULL)
1491 {
1492 return NULL;
1493 }
1494
1495 t = MsRegEnumKeyEx2(root, keyname, force32bit, force64bit);
1496
1497 if (t == NULL)
1498 {
1499 return NULL;
1500 }
1501
1502 b = NewBuf();
1503
1504 WriteBufInt(b, t->NumTokens);
1505
1506 for (i = 0;i < t->NumTokens;i++)
1507 {
1508 char *name = t->Token[i];
1509 char tmp[MAX_PATH];
1510 TOKEN_LIST *v;
1511
1512 Format(tmp, sizeof(tmp), "%s\\%s", keyname, name);
1513
1514 WriteBufStr(b, name);
1515
1516 v = MsRegEnumValueEx2(root, tmp, force32bit, force64bit);
1517 if (v == NULL)
1518 {
1519 WriteBufInt(b, 0);
1520 }
1521 else
1522 {
1523 UINT j;
1524
1525 WriteBufInt(b, v->NumTokens);
1526
1527 for (j = 0;j < v->NumTokens;j++)
1528 {
1529 char *valuename = v->Token[j];
1530 char *str;
1531
1532 WriteBufStr(b, valuename);
1533
1534 str = MsRegReadStrEx2(root, tmp, valuename, force32bit, force64bit);
1535 if (str != NULL)
1536 {
1537 WriteBufInt(b, 0);
1538 WriteBufStr(b, str);
1539 Free(str);
1540 }
1541 else
1542 {
1543 WriteBufInt(b, 1);
1544 WriteBufInt(b, MsRegReadIntEx2(root, tmp, valuename, force32bit, force64bit));
1545 }
1546 }
1547
1548 FreeToken(v);
1549 }
1550 }
1551
1552 FreeToken(t);
1553
1554 return b;
1555 }
1556
1557 // Get the process name of the specified process ID
MsGetProcessNameFromId(wchar_t * exename,UINT exename_size,UINT pid)1558 bool MsGetProcessNameFromId(wchar_t *exename, UINT exename_size, UINT pid)
1559 {
1560 LIST *o;
1561 bool ret = false;
1562 UINT i;
1563 // Validate arguments
1564 if (pid == 0)
1565 {
1566 return false;
1567 }
1568
1569 o = MsGetProcessList();
1570
1571 for (i = 0;i < LIST_NUM(o);i++)
1572 {
1573 MS_PROCESS *proc = LIST_DATA(o, i);
1574
1575 if (proc->ProcessId == pid)
1576 {
1577 if (exename != NULL)
1578 {
1579 UniStrCpy(exename, exename_size, proc->ExeFilenameW);
1580 }
1581
1582 ret = true;
1583 break;
1584 }
1585 }
1586
1587 MsFreeProcessList(o);
1588
1589 return ret;
1590 }
1591
1592 // Check whether the specified process ID exists
MsIsProcessIdExists(UINT pid)1593 bool MsIsProcessIdExists(UINT pid)
1594 {
1595 return MsGetProcessNameFromId(NULL, 0, pid);
1596 }
1597
1598 // Check whether the process of specified EXE file name exists
MsIsProcessExists(char * exename)1599 bool MsIsProcessExists(char *exename)
1600 {
1601 LIST *o;
1602 bool ret = false;
1603 UINT i;
1604 // Validate arguments
1605 if (exename == NULL)
1606 {
1607 return false;
1608 }
1609
1610 o = MsGetProcessList();
1611
1612 for (i = 0;i < LIST_NUM(o);i++)
1613 {
1614 MS_PROCESS *proc = LIST_DATA(o, i);
1615 char exe[MAX_PATH];
1616
1617 GetFileNameFromFilePath(exe, sizeof(exe), proc->ExeFilename);
1618
1619 if (StrCmpi(exename, exe) == 0)
1620 {
1621 ret = true;
1622 break;
1623 }
1624 }
1625
1626 MsFreeProcessList(o);
1627
1628 return ret;
1629 }
MsIsProcessExistsW(wchar_t * exename)1630 bool MsIsProcessExistsW(wchar_t *exename)
1631 {
1632 LIST *o;
1633 bool ret = false;
1634 UINT i;
1635 // Validate arguments
1636 if (exename == NULL)
1637 {
1638 return false;
1639 }
1640
1641 o = MsGetProcessList();
1642
1643 for (i = 0;i < LIST_NUM(o);i++)
1644 {
1645 MS_PROCESS *proc = LIST_DATA(o, i);
1646 wchar_t exe[MAX_PATH];
1647
1648 GetFileNameFromFilePathW(exe, sizeof(exe), proc->ExeFilenameW);
1649
1650 if (UniStrCmpi(exename, exe) == 0)
1651 {
1652 ret = true;
1653 break;
1654 }
1655 }
1656
1657 MsFreeProcessList(o);
1658
1659 return ret;
1660 }
1661
1662 typedef struct _ASTAT_
1663 {
1664 ADAPTER_STATUS adapt;
1665 NAME_BUFFER NameBuff[30];
1666 } ASTAT, *PASTAT;
1667
1668 // Get the precise time from the value of the high-resolution counter
MsGetHiResTimeSpan(UINT64 diff)1669 double MsGetHiResTimeSpan(UINT64 diff)
1670 {
1671 LARGE_INTEGER t;
1672 UINT64 freq;
1673
1674 if (QueryPerformanceFrequency(&t) == false)
1675 {
1676 freq = 1000ULL;
1677 }
1678 else
1679 {
1680 Copy(&freq, &t, sizeof(UINT64));
1681 }
1682
1683 return (double)diff / (double)freq;
1684 }
MsGetHiResTimeSpanUSec(UINT64 diff)1685 UINT64 MsGetHiResTimeSpanUSec(UINT64 diff)
1686 {
1687 LARGE_INTEGER t;
1688 UINT64 freq;
1689
1690 if (QueryPerformanceFrequency(&t) == false)
1691 {
1692 freq = 1000ULL;
1693 }
1694 else
1695 {
1696 Copy(&freq, &t, sizeof(UINT64));
1697 }
1698
1699 return (UINT64)(diff) * 1000ULL * 1000ULL / (UINT64)freq;
1700 }
1701
1702 // Get a high-resolution counter
MsGetHiResCounter()1703 UINT64 MsGetHiResCounter()
1704 {
1705 LARGE_INTEGER t;
1706 UINT64 ret;
1707
1708 if (QueryPerformanceCounter(&t) == false)
1709 {
1710 return Tick64();
1711 }
1712
1713 Copy(&ret, &t, sizeof(UINT64));
1714
1715 return ret;
1716 }
1717
1718 // Whether the Welcome screen is used
MsIsUseWelcomeLogin()1719 bool MsIsUseWelcomeLogin()
1720 {
1721 UINT os_type;
1722 if (MsIsNt() == false)
1723 {
1724 return false;
1725 }
1726
1727 os_type = GetOsInfo()->OsType;
1728
1729 if (OS_IS_WINDOWS_NT(os_type))
1730 {
1731 if (GET_KETA(os_type, 100) == 3)
1732 {
1733 if (MsRegReadIntEx2(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1734 "LogonType", false, true) == 0)
1735 {
1736 return false;
1737 }
1738 else
1739 {
1740 return true;
1741 }
1742 }
1743 }
1744
1745 return false;
1746 }
1747
1748 // Get a physical MAC address of the computer
MsGetPhysicalMacAddress(void * address)1749 bool MsGetPhysicalMacAddress(void *address)
1750 {
1751 // Validate arguments
1752 if (address == NULL)
1753 {
1754 return false;
1755 }
1756
1757 if (MsGetPhysicalMacAddressFromApi(address))
1758 {
1759 return true;
1760 }
1761
1762 if (MsGetPhysicalMacAddressFromNetbios(address))
1763 {
1764 return true;
1765 }
1766
1767 return false;
1768 }
1769
1770 // Get the physical MAC address (from API)
MsGetPhysicalMacAddressFromApi(void * address)1771 bool MsGetPhysicalMacAddressFromApi(void *address)
1772 {
1773 MS_ADAPTER_LIST *o;
1774 UINT i;
1775 bool ret = false;
1776 // Validate arguments
1777 if (address == NULL)
1778 {
1779 return false;
1780 }
1781
1782 Zero(address, 6);
1783
1784 o = MsCreateAdapterList();
1785
1786 for (i = 0;i < o->Num;i++)
1787 {
1788 MS_ADAPTER *a = o->Adapters[i];
1789
1790 if (a->AddressSize == 6 && a->Mtu == 1500)
1791 {
1792 bool b = false;
1793 switch (a->Type)
1794 {
1795 case MIB_IF_TYPE_OTHER:
1796 case MIB_IF_TYPE_ETHERNET:
1797 b = true;
1798 break;
1799
1800 case MIB_IF_TYPE_TOKENRING:
1801 case MIB_IF_TYPE_FDDI:
1802 case MIB_IF_TYPE_PPP:
1803 case MIB_IF_TYPE_LOOPBACK:
1804 case MIB_IF_TYPE_SLIP:
1805 b = false;
1806 break;
1807
1808 default:
1809 b = true;
1810 break;
1811 }
1812
1813 if (b)
1814 {
1815 if (SearchStrEx(a->Title, "WAN", 0, false) == INFINITE)
1816 {
1817 if (a->Status == MIB_IF_OPER_STATUS_CONNECTED || a->Status == MIB_IF_OPER_STATUS_OPERATIONAL)
1818 {
1819 if (a->AddressSize == 6)
1820 {
1821 if (IsZero(a->Address, 6) == false)
1822 {
1823 if (Cmp(address, a->Address, 6) <= 0)
1824 {
1825 Copy(address, a->Address, 6);
1826 ret = true;
1827 }
1828 }
1829 }
1830 }
1831 }
1832 }
1833 }
1834 }
1835
1836 MsFreeAdapterList(o);
1837
1838 return ret;
1839 }
1840
1841 // Get the physical MAC address (from NetBIOS)
MsGetPhysicalMacAddressFromNetbios(void * address)1842 bool MsGetPhysicalMacAddressFromNetbios(void *address)
1843 {
1844 NCB ncb;
1845 UCHAR ret;
1846 LANA_ENUM lenum;
1847 UINT i;
1848 ASTAT adapter;
1849 bool b = false;
1850 // Validate arguments
1851 if (address == NULL)
1852 {
1853 return false;
1854 }
1855
1856 Zero(&ncb, sizeof(ncb));
1857 Zero(&lenum, sizeof(lenum));
1858
1859 ncb.ncb_command = NCBENUM;
1860 ncb.ncb_buffer = (UCHAR *)&lenum;
1861 ncb.ncb_length = sizeof(lenum);
1862 ret = Netbios(&ncb);
1863
1864 Zero(address, 6);
1865
1866 for (i = 0;i < lenum.length;i++)
1867 {
1868 Zero(&ncb, sizeof(ncb));
1869 ncb.ncb_command = NCBRESET;
1870 ncb.ncb_lana_num = lenum.lana[i];
1871
1872 ret = Netbios(&ncb);
1873
1874 Zero(&ncb, sizeof(ncb));
1875 ncb.ncb_command = NCBASTAT;
1876 ncb.ncb_lana_num = lenum.lana[i];
1877
1878 StrCpy(ncb.ncb_callname, sizeof(ncb.ncb_callname), "* ");
1879 Zero(&adapter, sizeof(adapter));
1880 ncb.ncb_buffer = (char *)&adapter;
1881 ncb.ncb_length = sizeof(adapter);
1882
1883 ret = Netbios(&ncb);
1884
1885 if (ret == 0)
1886 {
1887 if (Cmp(address, adapter.adapt.adapter_address, 6) <= 0)
1888 {
1889 Copy(address, adapter.adapt.adapter_address, 6);
1890 b = true;
1891 }
1892 }
1893 }
1894
1895 return b;
1896 }
1897
1898 // System-wide updating notification
MsUpdateSystem()1899 void MsUpdateSystem()
1900 {
1901 static DWORD dw = 0;
1902
1903 SendMessageTimeoutA(HWND_BROADCAST, WM_WININICHANGE, 0, 0, SMTO_NORMAL, 1, (PDWORD_PTR)&dw);
1904 SleepThread(25);
1905 SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1, (PDWORD_PTR)&dw);
1906 SleepThread(25);
1907 SHChangeNotify(SHCNE_GLOBALEVENTS, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT | SHCNF_NOTIFYRECURSIVE, NULL, NULL);
1908 SleepThread(25);
1909 SHChangeNotify(SHCNE_GLOBALEVENTS, SHCNF_IDLIST, NULL, NULL);
1910 SleepThread(25);
1911 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT | SHCNF_NOTIFYRECURSIVE, NULL, NULL);
1912 SleepThread(25);
1913 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
1914 SleepThread(25);
1915 SHChangeNotify(SHCNE_ALLEVENTS, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT | SHCNF_NOTIFYRECURSIVE, NULL, NULL);
1916 SleepThread(25);
1917 SHChangeNotify(SHCNE_ALLEVENTS, SHCNF_IDLIST, NULL, NULL);
1918 SleepThread(25);
1919 }
1920
1921 // Get whether the specified path points to a local drive
MsIsLocalDrive(char * name)1922 bool MsIsLocalDrive(char *name)
1923 {
1924 char tmp[MAX_PATH];
1925 UINT ret;
1926
1927 // Validate arguments
1928 if (name == NULL)
1929 {
1930 return false;
1931 }
1932
1933 Zero(tmp, sizeof(tmp));
1934 InnerFilePath(tmp, sizeof(tmp), name);
1935
1936 if (StartWith(tmp, "\\\\"))
1937 {
1938 // Network directory
1939 return false;
1940 }
1941
1942 if (tmp[1] != ':' || tmp[2] != '\\')
1943 {
1944 // Not a drive letter
1945 return false;
1946 }
1947
1948 tmp[3] = 0;
1949
1950 ret = GetDriveType(tmp);
1951
1952 if (ret == DRIVE_REMOTE || ret == DRIVE_CDROM || ret == DRIVE_RAMDISK)
1953 {
1954 return false;
1955 }
1956
1957 return true;
1958 }
MsIsLocalDriveW(wchar_t * name)1959 bool MsIsLocalDriveW(wchar_t *name)
1960 {
1961 char name_a[MAX_PATH];
1962
1963 UniToStr(name_a, sizeof(name_a), name);
1964
1965 return MsIsLocalDrive(name_a);
1966 }
1967
1968 // Get whether the specified file is locked
MsIsFileLocked(char * name)1969 bool MsIsFileLocked(char *name)
1970 {
1971 HANDLE h;
1972 char tmp[MAX_PATH];
1973 // Validate arguments
1974 if (name == NULL)
1975 {
1976 return false;
1977 }
1978
1979 InnerFilePath(tmp, sizeof(tmp), name);
1980
1981 h = CreateFile(tmp, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
1982 if (h == INVALID_HANDLE_VALUE)
1983 {
1984 return true;
1985 }
1986
1987 CloseHandle(h);
1988
1989 return false;
1990 }
MsIsFileLockedW(wchar_t * name)1991 bool MsIsFileLockedW(wchar_t *name)
1992 {
1993 HANDLE h;
1994 wchar_t tmp[MAX_PATH];
1995 // Validate arguments
1996 if (name == NULL)
1997 {
1998 return false;
1999 }
2000
2001 if (IsNt() == false)
2002 {
2003 char name_a[MAX_SIZE];
2004
2005 UniToStr(name_a, sizeof(name_a), name);
2006
2007 return MsIsFileLocked(name_a);
2008 }
2009
2010 InnerFilePathW(tmp, sizeof(tmp), name);
2011
2012 h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
2013 if (h == INVALID_HANDLE_VALUE)
2014 {
2015 return true;
2016 }
2017
2018 CloseHandle(h);
2019
2020 return false;
2021 }
2022
2023 // Wait for the process termination
MsWaitProcessExit(void * process_handle)2024 UINT MsWaitProcessExit(void *process_handle)
2025 {
2026 HANDLE h = (HANDLE)process_handle;
2027 UINT ret = 1;
2028
2029 if (h == NULL)
2030 {
2031 return 1;
2032 }
2033
2034 while (true)
2035 {
2036 WaitForSingleObject(h, INFINITE);
2037
2038 ret = 1;
2039 if (GetExitCodeProcess(h, &ret) == false)
2040 {
2041 break;
2042 }
2043
2044 if (ret != STILL_ACTIVE)
2045 {
2046 break;
2047 }
2048 }
2049
2050 CloseHandle(h);
2051
2052 return ret;
2053 }
2054
2055 // Execution of the file (to get process handle)
MsExecuteEx(char * exe,char * arg,void ** process_handle)2056 bool MsExecuteEx(char *exe, char *arg, void **process_handle)
2057 {
2058 return MsExecuteEx2(exe, arg, process_handle, false);
2059 }
MsExecuteEx2(char * exe,char * arg,void ** process_handle,bool runas)2060 bool MsExecuteEx2(char *exe, char *arg, void **process_handle, bool runas)
2061 {
2062 SHELLEXECUTEINFO info;
2063 HANDLE h;
2064 // Validate arguments
2065 if (exe == NULL || process_handle == NULL)
2066 {
2067 return false;
2068 }
2069
2070 Zero(&info, sizeof(info));
2071 info.cbSize = sizeof(info);
2072 info.lpVerb = (runas ? "runas" : "open");
2073 info.lpFile = exe;
2074 info.fMask = SEE_MASK_NOCLOSEPROCESS;
2075 info.lpParameters = arg;
2076 info.nShow = SW_SHOWNORMAL;
2077 if (ShellExecuteEx(&info) == false)
2078 {
2079 return false;
2080 }
2081
2082 h = info.hProcess;
2083
2084 *process_handle = (void *)h;
2085
2086 return true;
2087 }
MsExecuteExW(wchar_t * exe,wchar_t * arg,void ** process_handle)2088 bool MsExecuteExW(wchar_t *exe, wchar_t *arg, void **process_handle)
2089 {
2090 return MsExecuteEx2W(exe, arg, process_handle, false);
2091 }
MsExecuteEx2W(wchar_t * exe,wchar_t * arg,void ** process_handle,bool runas)2092 bool MsExecuteEx2W(wchar_t *exe, wchar_t *arg, void **process_handle, bool runas)
2093 {
2094 SHELLEXECUTEINFOW info;
2095 HANDLE h;
2096 // Validate arguments
2097 if (exe == NULL || process_handle == NULL)
2098 {
2099 return false;
2100 }
2101
2102 if (IsNt() == false)
2103 {
2104 char exe_a[MAX_SIZE];
2105 char arg_a[MAX_SIZE];
2106
2107 UniToStr(exe_a, sizeof(exe_a), exe);
2108 UniToStr(arg_a, sizeof(arg_a), arg);
2109
2110 return MsExecuteEx(exe_a, arg_a, process_handle);
2111 }
2112
2113 Zero(&info, sizeof(info));
2114 info.cbSize = sizeof(info);
2115 info.lpVerb = (runas ? L"runas" : L"open");
2116 info.lpFile = exe;
2117 info.fMask = SEE_MASK_NOCLOSEPROCESS;
2118 info.lpParameters = arg;
2119 info.nShow = SW_SHOWNORMAL;
2120 if (ShellExecuteExW(&info) == false)
2121 {
2122 return false;
2123 }
2124
2125 h = info.hProcess;
2126
2127 *process_handle = (void *)h;
2128
2129 return true;
2130 }
2131
2132 // Close the handle
MsCloseHandle(void * handle)2133 void MsCloseHandle(void *handle)
2134 {
2135 if (handle != NULL)
2136 {
2137 CloseHandle(handle);
2138 }
2139 }
2140
2141 // Execution of the file
MsExecute(char * exe,char * arg)2142 bool MsExecute(char *exe, char *arg)
2143 {
2144 return MsExecute2(exe, arg, false);
2145 }
MsExecute2(char * exe,char * arg,bool runas)2146 bool MsExecute2(char *exe, char *arg, bool runas)
2147 {
2148 DWORD d;
2149 // Validate arguments
2150 if (exe == NULL)
2151 {
2152 return false;
2153 }
2154
2155 d = (DWORD)ShellExecuteA(NULL, (runas ? "runas" : "open"), exe, arg, MsGetExeDirName(), SW_SHOWNORMAL);
2156
2157 if (d > 32)
2158 {
2159 return true;
2160 }
2161
2162 return false;
2163 }
MsExecuteW(wchar_t * exe,wchar_t * arg)2164 bool MsExecuteW(wchar_t *exe, wchar_t *arg)
2165 {
2166 return MsExecute2W(exe, arg, false);
2167 }
MsExecute2W(wchar_t * exe,wchar_t * arg,bool runas)2168 bool MsExecute2W(wchar_t *exe, wchar_t *arg, bool runas)
2169 {
2170 DWORD d;
2171 // Validate arguments
2172 if (exe == NULL)
2173 {
2174 return false;
2175 }
2176
2177 if (IsNt() == false)
2178 {
2179 char exe_a[MAX_SIZE];
2180 char arg_a[MAX_SIZE];
2181
2182 UniToStr(exe_a, sizeof(exe_a), exe);
2183 UniToStr(arg_a, sizeof(arg_a), arg);
2184
2185 return MsExecute(exe_a, arg_a);
2186 }
2187
2188 d = (DWORD)ShellExecuteW(NULL, (runas ? L"runas" : L"open"), exe, arg, MsGetExeDirNameW(), SW_SHOWNORMAL);
2189
2190 if (d > 32)
2191 {
2192 return true;
2193 }
2194
2195 return false;
2196 }
2197
2198 // Recursive directory creation
MsUniMakeDirEx(wchar_t * name)2199 void MsUniMakeDirEx(wchar_t *name)
2200 {
2201 UINT wp;
2202 wchar_t *tmp;
2203 UINT i, len;
2204 // Validate arguments
2205 if (name == NULL)
2206 {
2207 return;
2208 }
2209
2210 tmp = ZeroMalloc(UniStrSize(name) * 2);
2211 wp = 0;
2212 len = UniStrLen(name);
2213 for (i = 0;i < len;i++)
2214 {
2215 wchar_t c = name[i];
2216
2217 if (c == '\\')
2218 {
2219 if (UniStrCmpi(tmp, L"\\\\") != 0 && UniStrCmpi(tmp, L"\\") != 0)
2220 {
2221 MsUniMakeDir(tmp);
2222 }
2223 }
2224
2225 tmp[wp++] = c;
2226 }
2227
2228 Free(tmp);
2229
2230 MsUniMakeDir(name);
2231 }
MsMakeDirEx(char * name)2232 void MsMakeDirEx(char *name)
2233 {
2234 wchar_t *name_w = CopyStrToUni(name);
2235
2236 MsUniMakeDirEx(name_w);
2237
2238 Free(name_w);
2239 }
2240
2241 // Create a directory
MsUniMakeDir(wchar_t * name)2242 bool MsUniMakeDir(wchar_t *name)
2243 {
2244 // Validate arguments
2245 if (name == NULL)
2246 {
2247 return false;
2248 }
2249
2250 if (MsIsNt() == false)
2251 {
2252 char *s = CopyUniToStr(name);
2253 bool ret = MsMakeDir(s);
2254 Free(s);
2255 return ret;
2256 }
2257
2258 return CreateDirectoryW(name, NULL);
2259 }
MsMakeDir(char * name)2260 bool MsMakeDir(char *name)
2261 {
2262 // Validate arguments
2263 if (name == NULL)
2264 {
2265 return false;
2266 }
2267
2268 return CreateDirectoryA(name, NULL);
2269 }
2270
2271 // Delete the directory
MsUniDirectoryDelete(wchar_t * name)2272 bool MsUniDirectoryDelete(wchar_t *name)
2273 {
2274 // Validate arguments
2275 if (name == NULL)
2276 {
2277 return false;
2278 }
2279
2280 if (MsIsNt() == false)
2281 {
2282 char *s = CopyUniToStr(name);
2283 bool ret = MsDirectoryDelete(s);
2284 Free(s);
2285 return ret;
2286 }
2287
2288 return RemoveDirectoryW(name);
2289 }
MsDirectoryDelete(char * name)2290 bool MsDirectoryDelete(char *name)
2291 {
2292 // Validate arguments
2293 if (name == NULL)
2294 {
2295 return false;
2296 }
2297
2298 return RemoveDirectoryA(name);
2299 }
2300
2301 // Delete the File
MsUniFileDelete(wchar_t * name)2302 bool MsUniFileDelete(wchar_t *name)
2303 {
2304 // Validate arguments
2305 if (name == NULL)
2306 {
2307 return false;
2308 }
2309
2310 if (MsIsNt() == false)
2311 {
2312 bool ret;
2313 char *s = CopyUniToStr(name);
2314 ret = MsFileDelete(s);
2315 Free(s);
2316 return ret;
2317 }
2318
2319 return DeleteFileW(name);
2320 }
MsFileDelete(char * name)2321 bool MsFileDelete(char *name)
2322 {
2323 // Validate arguments
2324 if (name == NULL)
2325 {
2326 return false;
2327 }
2328
2329 return DeleteFileA(name);
2330 }
2331
2332 // Get whether the specified file name is a directory
MsUniIsDirectory(wchar_t * name)2333 bool MsUniIsDirectory(wchar_t *name)
2334 {
2335 DWORD ret;
2336 // Validate arguments
2337 if (name == NULL)
2338 {
2339 return false;
2340 }
2341
2342 if (MsIsNt() == false)
2343 {
2344 char *s = CopyUniToStr(name);
2345 ret = MsIsDirectory(s);
2346 Free(s);
2347
2348 return ret;
2349 }
2350
2351 ret = GetFileAttributesW(name);
2352 if (ret == 0xffffffff)
2353 {
2354 return false;
2355 }
2356
2357 if (ret & FILE_ATTRIBUTE_DIRECTORY)
2358 {
2359 return true;
2360 }
2361
2362 return false;
2363 }
MsIsDirectoryW(wchar_t * name)2364 bool MsIsDirectoryW(wchar_t *name)
2365 {
2366 return MsUniIsDirectory(name);
2367 }
MsIsDirectory(char * name)2368 bool MsIsDirectory(char *name)
2369 {
2370 DWORD ret;
2371 char tmp[MAX_PATH];
2372 // Validate arguments
2373 if (name == NULL)
2374 {
2375 return false;
2376 }
2377
2378 InnerFilePath(tmp, sizeof(tmp), name);
2379
2380 ret = GetFileAttributesA(tmp);
2381 if (ret == 0xffffffff)
2382 {
2383 return false;
2384 }
2385
2386 if (ret & FILE_ATTRIBUTE_DIRECTORY)
2387 {
2388 return true;
2389 }
2390
2391 return false;
2392 }
2393
2394 // Extract the Cabinet from the MSI file
MsExtractCabFromMsi(char * msi,char * cab)2395 bool MsExtractCabFromMsi(char *msi, char *cab)
2396 {
2397 wchar_t msi_w[MAX_PATH];
2398 wchar_t cab_w[MAX_PATH];
2399
2400 StrToUni(msi_w, sizeof(msi_w), msi);
2401 StrToUni(cab_w, sizeof(cab_w), cab);
2402
2403 return MsExtractCabFromMsiW(msi_w, cab_w);
2404 }
MsExtractCabFromMsiW(wchar_t * msi,wchar_t * cab)2405 bool MsExtractCabFromMsiW(wchar_t *msi, wchar_t *cab)
2406 {
2407 BUF *b;
2408 bool ret = false;
2409 UINT i;
2410 char sign[] = {'M', 'S', 'C', 'F', 0, 0, 0, 0,};
2411 void *pointer = NULL;
2412 UINT current_pos = 0;
2413 UINT sign_size;
2414 // Validate arguments
2415 if (msi == NULL || cab == NULL)
2416 {
2417 return false;
2418 }
2419
2420 // Read the MSI
2421 b = ReadDumpW(msi);
2422 if (b == NULL)
2423 {
2424 return false;
2425 }
2426
2427 if (b->Size < 128)
2428 {
2429 FreeBuf(b);
2430 return false;
2431 }
2432
2433 sign_size = sizeof(sign);
2434
2435 // Search for "MSCF"
2436 for (i = 0;i < (b->Size - sign_size);i++)
2437 {
2438 char *p = ((UCHAR *)b->Buf) + i;
2439
2440 if (Cmp(p, sign, sign_size) == 0)
2441 {
2442 pointer = p;
2443 current_pos = i;
2444 }
2445 }
2446
2447 if (pointer != NULL)
2448 {
2449 UINT size = b->Size - current_pos;
2450 BUF *b2 = NewBuf();
2451
2452 WriteBuf(b2, pointer, size);
2453
2454 ret = DumpBufW(b2, cab);
2455
2456 FreeBuf(b2);
2457
2458 }
2459
2460 FreeBuf(b);
2461
2462 return ret;
2463 }
2464
2465 // Retrieve a file from Cabinet file
MsExtractCab(char * cab_name,char * dest_dir_name)2466 bool MsExtractCab(char *cab_name, char *dest_dir_name)
2467 {
2468 wchar_t cab_name_w[MAX_SIZE];
2469 wchar_t dest_dir_name_w[MAX_SIZE];
2470
2471 StrToUni(cab_name_w, sizeof(cab_name_w), cab_name);
2472 StrToUni(dest_dir_name_w, sizeof(dest_dir_name_w), dest_dir_name);
2473
2474 return MsExtractCabW(cab_name_w, dest_dir_name_w);
2475 }
MsExtractCabW(wchar_t * cab_name,wchar_t * dest_dir_name)2476 bool MsExtractCabW(wchar_t *cab_name, wchar_t *dest_dir_name)
2477 {
2478 wchar_t cabarc[MAX_PATH];
2479 wchar_t arg[MAX_PATH * 2];
2480 wchar_t tmp[MAX_PATH];
2481
2482 // Validate arguments
2483 if (cab_name == NULL || dest_dir_name == NULL)
2484 {
2485 return false;
2486 }
2487
2488 if (MsGetCabarcExeFilenameW(cabarc, sizeof(cabarc)) == false)
2489 {
2490 return false;
2491 }
2492
2493 UniStrCpy(tmp, sizeof(tmp), dest_dir_name);
2494 if (UniEndWith(tmp, L"\\"))
2495 {
2496 tmp[UniStrLen(tmp) - 1] = 0;
2497 }
2498
2499 UniFormat(arg, sizeof(arg),
2500 L"-o X \"%s\" * \"%s\"\\",
2501 cab_name,
2502 tmp);
2503
2504 MakeDirW(dest_dir_name);
2505
2506 if (RunW(cabarc, arg, true, true) == false)
2507 {
2508 return false;
2509 }
2510
2511 return true;
2512 }
2513
2514 // Extract of cabarc.exe
MsGetCabarcExeFilename(char * name,UINT size)2515 bool MsGetCabarcExeFilename(char *name, UINT size)
2516 {
2517 // Validate arguments
2518 if (name == NULL)
2519 {
2520 return false;
2521 }
2522
2523 ConbinePath(name, size, MsGetMyTempDir(), "cabarc.exe");
2524
2525 if (IsFileExists(name))
2526 {
2527 return true;
2528 }
2529
2530 if (FileCopy("|cabarc.exe", name) == false)
2531 {
2532 return false;
2533 }
2534
2535 return true;
2536 }
MsGetCabarcExeFilenameW(wchar_t * name,UINT size)2537 bool MsGetCabarcExeFilenameW(wchar_t *name, UINT size)
2538 {
2539 // Validate arguments
2540 if (name == NULL)
2541 {
2542 return false;
2543 }
2544
2545 ConbinePathW(name, size, MsGetMyTempDirW(), L"cabarc.exe");
2546
2547 if (IsFileExistsW(name))
2548 {
2549 return true;
2550 }
2551
2552 if (FileCopyW(L"|cabarc.exe", name) == false)
2553 {
2554 return false;
2555 }
2556
2557 return true;
2558 }
2559
2560 // Extract the Cabinet file from EXE file
MsExtractCabinetFileFromExe(char * exe,char * cab)2561 bool MsExtractCabinetFileFromExe(char *exe, char *cab)
2562 {
2563 BUF *b;
2564 // Validate arguments
2565 if (exe == NULL || cab == NULL)
2566 {
2567 return false;
2568 }
2569
2570 b = MsExtractResourceFromExe(exe, RT_RCDATA, "CABINET");
2571 if (b == NULL)
2572 {
2573 return false;
2574 }
2575
2576 if (DumpBuf(b, cab) == false)
2577 {
2578 FreeBuf(b);
2579
2580 return false;
2581 }
2582
2583 FreeBuf(b);
2584
2585 return true;
2586 }
MsExtractCabinetFileFromExeW(wchar_t * exe,wchar_t * cab)2587 bool MsExtractCabinetFileFromExeW(wchar_t *exe, wchar_t *cab)
2588 {
2589 BUF *b;
2590 // Validate arguments
2591 if (exe == NULL || cab == NULL)
2592 {
2593 return false;
2594 }
2595
2596 b = MsExtractResourceFromExeW(exe, RT_RCDATA, "CABINET");
2597 if (b == NULL)
2598 {
2599 return false;
2600 }
2601
2602 if (DumpBufW(b, cab) == false)
2603 {
2604 FreeBuf(b);
2605
2606 return false;
2607 }
2608
2609 FreeBuf(b);
2610
2611 return true;
2612 }
2613
2614 // Extract the resource from EXE file
MsExtractResourceFromExe(char * exe,char * type,char * name)2615 BUF *MsExtractResourceFromExe(char *exe, char *type, char *name)
2616 {
2617 HINSTANCE h;
2618 HRSRC hr;
2619 HGLOBAL hg;
2620 UINT size;
2621 void *data;
2622 BUF *buf;
2623 // Validate arguments
2624 if (exe == NULL || type == NULL || name == NULL)
2625 {
2626 return NULL;
2627 }
2628
2629 h = LoadLibraryExA(exe, NULL, LOAD_LIBRARY_AS_DATAFILE);
2630 if (h == NULL)
2631 {
2632 return NULL;
2633 }
2634
2635 hr = FindResourceA(h, name, type);
2636 if (hr == NULL)
2637 {
2638 FreeLibrary(h);
2639 return NULL;
2640 }
2641
2642 hg = LoadResource(h, hr);
2643 if (hg == NULL)
2644 {
2645 FreeLibrary(h);
2646 return NULL;
2647 }
2648
2649 size = SizeofResource(h, hr);
2650 data = (void *)LockResource(hg);
2651
2652 buf = NewBuf();
2653 WriteBuf(buf, data, size);
2654
2655 FreeResource(hg);
2656 FreeLibrary(h);
2657
2658 SeekBuf(buf, 0, 0);
2659
2660 return buf;
2661 }
MsExtractResourceFromExeW(wchar_t * exe,char * type,char * name)2662 BUF *MsExtractResourceFromExeW(wchar_t *exe, char *type, char *name)
2663 {
2664 HINSTANCE h;
2665 HRSRC hr;
2666 HGLOBAL hg;
2667 UINT size;
2668 void *data;
2669 BUF *buf;
2670 // Validate arguments
2671 if (exe == NULL || type == NULL || name == NULL)
2672 {
2673 return NULL;
2674 }
2675
2676 if (IsNt() == false)
2677 {
2678 char exe_a[MAX_PATH];
2679
2680 UniToStr(exe_a, sizeof(exe_a), exe);
2681
2682 return MsExtractResourceFromExe(exe_a, type, name);
2683 }
2684
2685 h = LoadLibraryExW(exe, NULL, LOAD_LIBRARY_AS_DATAFILE);
2686 if (h == NULL)
2687 {
2688 return NULL;
2689 }
2690
2691 hr = FindResource(h, name, type);
2692 if (hr == NULL)
2693 {
2694 FreeLibrary(h);
2695 return NULL;
2696 }
2697
2698 hg = LoadResource(h, hr);
2699 if (hg == NULL)
2700 {
2701 FreeLibrary(h);
2702 return NULL;
2703 }
2704
2705 size = SizeofResource(h, hr);
2706 data = (void *)LockResource(hg);
2707
2708 buf = NewBuf();
2709 WriteBuf(buf, data, size);
2710
2711 FreeResource(hg);
2712 FreeLibrary(h);
2713
2714 SeekBuf(buf, 0, 0);
2715
2716 return buf;
2717 }
2718
2719 // Get the version information of the file
MsGetFileVersion(char * name,UINT * v1,UINT * v2,UINT * v3,UINT * v4)2720 bool MsGetFileVersion(char *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4)
2721 {
2722 void *data;
2723 UINT size;
2724 DWORD h;
2725 bool ret = false;
2726 // Validate arguments
2727 if (name == NULL)
2728 {
2729 return false;
2730 }
2731
2732 h = 0;
2733 size = GetFileVersionInfoSize(name, &h);
2734 if (size == 0)
2735 {
2736 return false;
2737 }
2738
2739 data = ZeroMalloc(size);
2740
2741 if (GetFileVersionInfoA(name, 0, size, data))
2742 {
2743 VS_FIXEDFILEINFO *info = NULL;
2744 UINT info_size = 0;
2745 if (VerQueryValueA(data, "\\", &info, &info_size))
2746 {
2747 if (v1 != NULL)
2748 {
2749 *v1 = HIWORD(info->dwFileVersionMS);
2750 }
2751
2752 if (v2 != NULL)
2753 {
2754 *v2 = LOWORD(info->dwFileVersionMS);
2755 }
2756
2757 if (v3 != NULL)
2758 {
2759 *v3 = HIWORD(info->dwFileVersionLS);
2760 }
2761
2762 if (v4 != NULL)
2763 {
2764 *v4 = LOWORD(info->dwFileVersionLS);
2765 }
2766
2767 ret = true;
2768 }
2769 }
2770
2771 Free(data);
2772
2773 return ret;
2774 }
MsGetFileVersionW(wchar_t * name,UINT * v1,UINT * v2,UINT * v3,UINT * v4)2775 bool MsGetFileVersionW(wchar_t *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4)
2776 {
2777 void *data;
2778 UINT size;
2779 DWORD h;
2780 bool ret = false;
2781 // Validate arguments
2782 if (name == NULL)
2783 {
2784 return false;
2785 }
2786
2787 if (IsNt() == false)
2788 {
2789 char name_a[MAX_PATH];
2790
2791 UniToStr(name_a, sizeof(name_a), name);
2792
2793 return MsGetFileVersion(name_a, v1, v2, v3, v4);
2794 }
2795
2796 h = 0;
2797 size = GetFileVersionInfoSizeW(name, &h);
2798 if (size == 0)
2799 {
2800 return false;
2801 }
2802
2803 data = ZeroMalloc(size);
2804
2805 if (GetFileVersionInfoW(name, 0, size, data))
2806 {
2807 VS_FIXEDFILEINFO *info = NULL;
2808 UINT info_size = 0;
2809 if (VerQueryValue(data, "\\", &info, &info_size))
2810 {
2811 if (v1 != NULL)
2812 {
2813 *v1 = HIWORD(info->dwFileVersionMS);
2814 }
2815
2816 if (v2 != NULL)
2817 {
2818 *v2 = LOWORD(info->dwFileVersionMS);
2819 }
2820
2821 if (v3 != NULL)
2822 {
2823 *v3 = HIWORD(info->dwFileVersionLS);
2824 }
2825
2826 if (v4 != NULL)
2827 {
2828 *v4 = LOWORD(info->dwFileVersionLS);
2829 }
2830
2831 ret = true;
2832 }
2833 }
2834
2835 Free(data);
2836
2837 return ret;
2838 }
2839
2840 // Set the file to a hidden file
MsSetFileToHidden(char * name)2841 void MsSetFileToHidden(char *name)
2842 {
2843 char tmp[MAX_PATH];
2844 DWORD d;
2845 // Validate arguments
2846 if (name == NULL)
2847 {
2848 return;
2849 }
2850
2851 NormalizePath(tmp, sizeof(tmp), name);
2852
2853 d = GetFileAttributesA(tmp);
2854 if (d != INVALID_FILE_ATTRIBUTES)
2855 {
2856 d |= FILE_ATTRIBUTE_HIDDEN;
2857
2858 SetFileAttributesA(tmp, d);
2859 }
2860 }
MsSetFileToHiddenW(wchar_t * name)2861 void MsSetFileToHiddenW(wchar_t *name)
2862 {
2863 wchar_t tmp[MAX_PATH];
2864 DWORD d;
2865 // Validate arguments
2866 if (name == NULL)
2867 {
2868 return;
2869 }
2870
2871 if (IsNt() == false)
2872 {
2873 char name_a[MAX_SIZE];
2874
2875 UniToStr(name_a, sizeof(name_a), name);
2876
2877 MsSetFileToHidden(name_a);
2878
2879 return;
2880 }
2881
2882 NormalizePathW(tmp, sizeof(tmp), name);
2883
2884 d = GetFileAttributesW(tmp);
2885 if (d != INVALID_FILE_ATTRIBUTES)
2886 {
2887 d |= FILE_ATTRIBUTE_HIDDEN;
2888
2889 SetFileAttributesW(tmp, d);
2890 }
2891 }
2892
2893 // Sleep prevention thread
MsNoSleepThread(THREAD * thread,void * param)2894 void MsNoSleepThread(THREAD *thread, void *param)
2895 {
2896 MS_NOSLEEP *e;
2897 EXECUTION_STATE (WINAPI *_SetThreadExecutionState)(EXECUTION_STATE);
2898 HINSTANCE hKernel32;
2899 // Validate arguments
2900 if (thread == NULL || param == NULL)
2901 {
2902 return;
2903 }
2904
2905 hKernel32 = LoadLibrary("kernel32.dll");
2906
2907 _SetThreadExecutionState =
2908 (EXECUTION_STATE (__stdcall *)(EXECUTION_STATE))
2909 GetProcAddress(hKernel32, "SetThreadExecutionState");
2910
2911 e = (MS_NOSLEEP *)param;
2912
2913 while (e->Halt == false)
2914 {
2915 DWORD flag = ES_SYSTEM_REQUIRED;
2916
2917 if (e->NoScreenSaver)
2918 {
2919 flag |= ES_DISPLAY_REQUIRED;
2920 }
2921
2922 if (_SetThreadExecutionState != NULL)
2923 {
2924 _SetThreadExecutionState(flag);
2925 }
2926
2927 Wait(e->HaltEvent, 30 * 1000);
2928 }
2929
2930 FreeLibrary(hKernel32);
2931 }
2932
2933 // Sleep prevention thread (for Windows Vista)
MsNoSleepThreadVista(THREAD * thread,void * param)2934 void MsNoSleepThreadVista(THREAD *thread, void *param)
2935 {
2936 MS_NOSLEEP *e;
2937 char *key = "Control Panel\\Desktop";
2938 UINT64 last_set_flag = 0;
2939 UINT last_c_x = INFINITE, last_c_y = INFINITE;
2940 UINT64 last_mouse_move_time = 0;
2941 EXECUTION_STATE (WINAPI *_SetThreadExecutionState)(EXECUTION_STATE);
2942 HINSTANCE hKernel32;
2943 // Validate arguments
2944 if (thread == NULL || param == NULL)
2945 {
2946 return;
2947 }
2948
2949 hKernel32 = LoadLibrary("kernel32.dll");
2950
2951 _SetThreadExecutionState =
2952 (EXECUTION_STATE (__stdcall *)(EXECUTION_STATE))
2953 GetProcAddress(hKernel32, "SetThreadExecutionState");
2954
2955 e = (MS_NOSLEEP *)param;
2956
2957 while (e->Halt == false)
2958 {
2959 DWORD flag = ES_SYSTEM_REQUIRED;
2960 UINT64 now = Tick64();
2961 POINT p;
2962 bool mouse_move = false;
2963
2964 Zero(&p, sizeof(p));
2965 GetCursorPos(&p);
2966
2967 if (p.x != last_c_x || p.y != last_c_y)
2968 {
2969 if (last_c_x != INFINITE && last_c_y != INFINITE)
2970 {
2971 mouse_move = true;
2972 }
2973
2974 last_c_x = p.x;
2975 last_c_y = p.y;
2976 }
2977
2978 if (mouse_move)
2979 {
2980 last_mouse_move_time = now;
2981 }
2982
2983 if (last_mouse_move_time == 0 || (now > (last_mouse_move_time + 50000ULL)))
2984 {
2985 wchar_t *active;
2986 wchar_t *exe;
2987 // Remove the configuration of the screen saver If the mouse does not move more than 50 seconds
2988
2989 active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");
2990 exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");
2991
2992 if (UniToInt(active) != 0 && UniIsEmptyStr(exe) == false)
2993 {
2994 // Screen saver is set
2995 UniStrCpy(e->ScreenSaveActive, sizeof(e->ScreenSaveActive), active);
2996 UniStrCpy(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE), exe);
2997
2998 MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", L"0");
2999 MsRegDeleteValue(REG_CURRENT_USER, key, "SCRNSAVE.EXE");
3000
3001 Debug("Push SS Settings.\n");
3002 }
3003
3004 Free(active);
3005 Free(exe);
3006
3007 last_mouse_move_time = now;
3008 }
3009 else
3010 {
3011 if (mouse_move)
3012 {
3013 if (UniIsEmptyStr(e->ScreenSaveActive) == false && UniIsEmptyStr(e->SCRNSAVE_EXE) == false)
3014 {
3015 // Restore the settings of screen saver if the screen saver
3016 // is not set when the mouse is moved
3017 wchar_t *active;
3018 wchar_t *exe;
3019
3020 active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");
3021 exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");
3022
3023 if (UniToInt(active) != 0 && UniIsEmptyStr(exe) == false)
3024 {
3025 }
3026 else
3027 {
3028 MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", e->ScreenSaveActive);
3029 MsRegWriteStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE", e->SCRNSAVE_EXE);
3030
3031 Zero(e->ScreenSaveActive, sizeof(e->ScreenSaveActive));
3032 Zero(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE));
3033
3034 Debug("Pop SS Settings.\n");
3035 }
3036
3037 Free(active);
3038 Free(exe);
3039 }
3040 }
3041 }
3042
3043 if (last_set_flag == 0 || (now > (last_set_flag + 50000ULL)))
3044 {
3045 // Flag set (interval 50 seconds)
3046 last_set_flag = now;
3047
3048 if (_SetThreadExecutionState != NULL)
3049 {
3050 _SetThreadExecutionState(flag);
3051 }
3052 }
3053
3054 Wait(e->HaltEvent, 512);
3055 }
3056
3057 if (true)
3058 {
3059 // Restore the settings of the screen saver
3060 wchar_t *active;
3061 wchar_t *exe;
3062
3063 if (UniIsEmptyStr(e->ScreenSaveActive) == false && UniIsEmptyStr(e->SCRNSAVE_EXE) == false)
3064 {
3065 active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");
3066 exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");
3067
3068 if (UniToInt(active) != 0 && UniIsEmptyStr(exe) != 0)
3069 {
3070 }
3071 else
3072 {
3073 MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", e->ScreenSaveActive);
3074 MsRegWriteStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE", e->SCRNSAVE_EXE);
3075
3076 Zero(e->ScreenSaveActive, sizeof(e->ScreenSaveActive));
3077 Zero(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE));
3078
3079 Debug("Pop SS Settings.\n");
3080 }
3081
3082 Free(active);
3083 Free(exe);
3084 }
3085 }
3086
3087 FreeLibrary(hKernel32);
3088 }
3089
3090 // The start of the sleep prevention
MsNoSleepStart(bool no_screensaver)3091 void *MsNoSleepStart(bool no_screensaver)
3092 {
3093 MS_NOSLEEP *e;
3094 bool is_vista = MsIsVista();
3095 bool is_nt_4 = false;
3096 UINT os_type = GetOsInfo()->OsType;
3097
3098 if (OS_IS_WINDOWS_NT(os_type))
3099 {
3100 if (GET_KETA(os_type, 100) == 1)
3101 {
3102 is_nt_4 = true;
3103 }
3104 }
3105
3106 e = ZeroMalloc(sizeof(MS_NOSLEEP));
3107
3108 e->HaltEvent = NewEvent();
3109 e->NoScreenSaver = no_screensaver;
3110
3111 if (e->NoScreenSaver == false || (is_vista == false && is_nt_4 == false))
3112 {
3113 e->Thread = NewThread(MsNoSleepThread, e);
3114 }
3115 else
3116 {
3117 e->Thread = NewThread(MsNoSleepThreadVista, e);
3118 }
3119
3120 return (void *)e;
3121 }
3122
3123 // Stop the Sleep prevention
MsNoSleepEnd(void * p)3124 void MsNoSleepEnd(void *p)
3125 {
3126 MS_NOSLEEP *e;
3127 // Validate arguments
3128 if (p == NULL)
3129 {
3130 return;
3131 }
3132
3133 e = (MS_NOSLEEP *)p;
3134
3135 e->Halt = true;
3136 Set(e->HaltEvent);
3137
3138 WaitThread(e->Thread, INFINITE);
3139 ReleaseThread(e->Thread);
3140 ReleaseEvent(e->HaltEvent);
3141
3142 Free(e);
3143 }
3144
3145 static wchar_t ms_computer_name_full_cache[MAX_SIZE] = {0};
3146
3147 // Get the full name of the computer
MsGetComputerNameFull(wchar_t * name,UINT size)3148 void MsGetComputerNameFull(wchar_t *name, UINT size)
3149 {
3150 MsGetComputerNameFullEx(name, size, false);
3151 }
MsGetComputerNameFullEx(wchar_t * name,UINT size,bool with_cache)3152 void MsGetComputerNameFullEx(wchar_t *name, UINT size, bool with_cache)
3153 {
3154 UINT size2 = size;
3155 // Validate arguments
3156 UniStrCpy(name, size, L"");
3157 if (name == NULL || size == 0)
3158 {
3159 return;
3160 }
3161
3162 if (with_cache)
3163 {
3164 if (UniIsEmptyStr(ms_computer_name_full_cache) == false)
3165 {
3166 UniStrCpy(name, size, ms_computer_name_full_cache);
3167 return;
3168 }
3169 }
3170
3171 if (MsIsNt() == false || ms->nt->GetComputerNameExW == NULL ||
3172 ms->nt->GetComputerNameExW(ComputerNameDnsFullyQualified, name, &size2) == false)
3173 {
3174 char tmp[MAX_SIZE];
3175
3176 MsGetComputerName(tmp, sizeof(tmp));
3177
3178 StrToUni(name, size, tmp);
3179 }
3180
3181 if (with_cache)
3182 {
3183 UniStrCpy(ms_computer_name_full_cache, sizeof(ms_computer_name_full_cache), name);
3184 }
3185 }
3186
3187 // Get the computer name
MsGetComputerName(char * name,UINT size)3188 void MsGetComputerName(char *name, UINT size)
3189 {
3190 DWORD sz;
3191 // Validate arguments
3192 if (name == NULL)
3193 {
3194 return;
3195 }
3196
3197 sz = size;
3198 GetComputerName(name, &sz);
3199 }
3200
3201 // Get the hash value of the position of the mouse cursor
MsGetCursorPosHash()3202 UINT MsGetCursorPosHash()
3203 {
3204 POINT p;
3205
3206 Zero(&p, sizeof(p));
3207
3208 if (GetCursorPos(&p) == false)
3209 {
3210 return 0;
3211 }
3212
3213 return MAKELONG((USHORT)p.x, (USHORT)p.y);
3214 }
3215
3216 // Start the process as a standard user privileges
MsRunAsUserEx(char * filename,char * arg,bool hide)3217 void *MsRunAsUserEx(char *filename, char *arg, bool hide)
3218 {
3219 void *ret = MsRunAsUserExInner(filename, arg, hide);
3220
3221 if (ret == NULL)
3222 {
3223 Debug("MsRunAsUserExInner Failed.\n");
3224 ret = Win32RunEx(filename, arg, hide);
3225 }
3226
3227 return ret;
3228 }
MsRunAsUserExW(wchar_t * filename,wchar_t * arg,bool hide)3229 void *MsRunAsUserExW(wchar_t *filename, wchar_t *arg, bool hide)
3230 {
3231 void *ret = MsRunAsUserExInnerW(filename, arg, hide);
3232
3233 if (ret == NULL)
3234 {
3235 Debug("MsRunAsUserExInner Failed.\n");
3236 ret = Win32RunExW(filename, arg, hide);
3237 }
3238
3239 return ret;
3240 }
MsRunAsUserExInner(char * filename,char * arg,bool hide)3241 void *MsRunAsUserExInner(char *filename, char *arg, bool hide)
3242 {
3243 void *ret;
3244 wchar_t *filename_w;
3245 wchar_t *arg_w;
3246
3247 filename_w = CopyStrToUni(filename);
3248 arg_w = CopyStrToUni(arg);
3249
3250 ret = MsRunAsUserExInnerW(filename_w, arg_w, hide);
3251
3252 Free(filename_w);
3253 Free(arg_w);
3254
3255 return ret;
3256 }
MsRunAsUserExInnerW(wchar_t * filename,wchar_t * arg,bool hide)3257 void *MsRunAsUserExInnerW(wchar_t *filename, wchar_t *arg, bool hide)
3258 {
3259 STARTUPINFOW info;
3260 PROCESS_INFORMATION ret;
3261 wchar_t cmdline[MAX_SIZE];
3262 wchar_t name[MAX_PATH];
3263 HANDLE hToken;
3264 // Validate arguments
3265 if (filename == NULL)
3266 {
3267 return NULL;
3268 }
3269
3270 if (MsIsVista() == false)
3271 {
3272 // Can not be used in non-Windows Vista
3273 return NULL;
3274 }
3275
3276 UniStrCpy(name, sizeof(name), filename);
3277 UniTrim(name);
3278
3279 if (UniSearchStr(name, L"\"", 0) == INFINITE)
3280 {
3281 if (arg == NULL)
3282 {
3283 UniFormat(cmdline, sizeof(cmdline), L"%s", name);
3284 }
3285 else
3286 {
3287 UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);
3288 }
3289 }
3290 else
3291 {
3292 if (arg == NULL)
3293 {
3294 UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);
3295 }
3296 else
3297 {
3298 UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);
3299 }
3300 }
3301
3302 Zero(&info, sizeof(info));
3303 Zero(&ret, sizeof(ret));
3304 info.cb = sizeof(info);
3305 info.dwFlags = STARTF_USESHOWWINDOW;
3306 info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
3307
3308 UniTrim(cmdline);
3309
3310 hToken = MsCreateUserToken();
3311
3312 if (hToken == NULL)
3313 {
3314 return NULL;
3315 }
3316
3317 if (ms->nt->CreateProcessAsUserW(hToken, NULL, cmdline, NULL, NULL, FALSE,
3318 (hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
3319 NULL, NULL, &info, &ret) == FALSE)
3320 {
3321 return NULL;
3322 }
3323
3324 CloseHandle(hToken);
3325
3326 CloseHandle(ret.hThread);
3327 return ret.hProcess;
3328 }
3329
3330 // Get the SID from the account name
MsGetSidFromAccountName(char * name)3331 SID *MsGetSidFromAccountName(char *name)
3332 {
3333 SID *sid;
3334 UINT sid_size = 4096;
3335 char *domain_name;
3336 UINT domain_name_size = 4096;
3337 SID_NAME_USE use = SidTypeUser;
3338 // Validate arguments
3339 if (name == NULL)
3340 {
3341 return NULL;
3342 }
3343
3344 if (MsIsNt() == false)
3345 {
3346 return NULL;
3347 }
3348
3349 sid = ZeroMalloc(sid_size);
3350 domain_name = ZeroMalloc(domain_name_size);
3351
3352 if (ms->nt->LookupAccountNameA(NULL, name, sid, &sid_size, domain_name, &domain_name_size, &use) == false)
3353 {
3354 Free(sid);
3355 Free(domain_name);
3356 return NULL;
3357 }
3358
3359 Free(domain_name);
3360
3361 return sid;
3362 }
3363
3364 // Release the SID
MsFreeSid(SID * sid)3365 void MsFreeSid(SID *sid)
3366 {
3367 // Validate arguments
3368 if (sid == NULL)
3369 {
3370 return;
3371 }
3372
3373 Free(sid);
3374 }
3375
3376 // Create a token of standard user
MsCreateUserToken()3377 HANDLE MsCreateUserToken()
3378 {
3379 char *medium_sid = "S-1-16-8192";
3380 char *administrators_sid = "S-1-5-32-544";
3381 SID *sid = NULL;
3382 TOKEN_MANDATORY_LABEL til;
3383 HANDLE hCurrentToken, hNewToken;
3384 if (MsIsNt() == false)
3385 {
3386 return NULL;
3387 }
3388 if (ms->nt->ConvertStringSidToSidA == NULL ||
3389 ms->nt->OpenProcessToken == NULL ||
3390 ms->nt->DuplicateTokenEx == NULL ||
3391 ms->nt->GetTokenInformation == NULL ||
3392 ms->nt->SetTokenInformation == NULL)
3393 {
3394 return NULL;
3395 }
3396
3397 Zero(&til, sizeof(til));
3398
3399 if (ms->nt->ConvertStringSidToSidA(medium_sid, &sid) == false)
3400 {
3401 return NULL;
3402 }
3403
3404 til.Label.Attributes = SE_GROUP_INTEGRITY;
3405 til.Label.Sid = sid;
3406
3407 if (ms->nt->OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hCurrentToken) == false)
3408 {
3409 LocalFree(sid);
3410 return NULL;
3411 }
3412
3413 if (ms->nt->DuplicateTokenEx(hCurrentToken, MAXIMUM_ALLOWED, NULL,
3414 SecurityImpersonation, TokenPrimary, &hNewToken) == false)
3415 {
3416 CloseHandle(hCurrentToken);
3417 LocalFree(sid);
3418 return NULL;
3419 }
3420
3421 if (ms->nt->SetTokenInformation(hNewToken, VistaTokenIntegrityLevel, &til,
3422 sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(sid)) == false)
3423 {
3424 CloseHandle(hNewToken);
3425 CloseHandle(hCurrentToken);
3426 LocalFree(sid);
3427 return NULL;
3428 }
3429
3430 CloseHandle(hCurrentToken);
3431 LocalFree(sid);
3432
3433 return hNewToken;
3434 }
3435
3436
3437 // Check whether SHA-2 kernel mode signature is supported
MsIsSha2KernelModeSignatureSupported()3438 bool MsIsSha2KernelModeSignatureSupported()
3439 {
3440 HINSTANCE hDll;
3441 bool ret = false;
3442
3443 if (MsIsWindows8())
3444 {
3445 return true;
3446 }
3447
3448 hDll = LoadLibrary("Wintrust.dll");
3449 if (hDll == NULL)
3450 {
3451 return false;
3452 }
3453
3454 if (GetProcAddress(hDll, "CryptCATAdminAcquireContext2") != NULL)
3455 {
3456 ret = true;
3457 }
3458
3459 FreeLibrary(hDll);
3460
3461 return ret;
3462 }
3463
3464 // Check whether KB3033929 is required
MsIsKB3033929RequiredAndMissing()3465 bool MsIsKB3033929RequiredAndMissing()
3466 {
3467 OS_INFO *info = GetOsInfo();
3468
3469 if (info == NULL)
3470 {
3471 return false;
3472 }
3473
3474 if (OS_IS_WINDOWS_NT(info->OsType))
3475 {
3476 if (GET_KETA(info->OsType, 100) == 6)
3477 {
3478 if (MsIsX64())
3479 {
3480 if (MsIsSha2KernelModeSignatureSupported() == false)
3481 {
3482 return true;
3483 }
3484 }
3485 }
3486 }
3487
3488 return false;
3489 }
3490
3491 // Check the digital signature of the file
MsCheckFileDigitalSignature(HWND hWnd,char * name,bool * danger)3492 bool MsCheckFileDigitalSignature(HWND hWnd, char *name, bool *danger)
3493 {
3494 wchar_t tmp[MAX_PATH];
3495
3496 swprintf(tmp, sizeof(tmp), L"%S", name);
3497
3498 return MsCheckFileDigitalSignatureW(hWnd, tmp, danger);
3499 }
MsCheckFileDigitalSignatureW(HWND hWnd,wchar_t * name,bool * danger)3500 bool MsCheckFileDigitalSignatureW(HWND hWnd, wchar_t *name, bool *danger)
3501 {
3502 HRESULT ret = S_OK;
3503 wchar_t *tmp;
3504 LONG (WINAPI *_WinVerifyTrust)(HWND, GUID *, LPVOID) = NULL;
3505 HINSTANCE hDll;
3506 // Validate arguments
3507 if (name == NULL)
3508 {
3509 return false;
3510 }
3511
3512 if (danger != NULL)
3513 {
3514 *danger = false;
3515 }
3516
3517 tmp = name;
3518
3519 hDll = LoadLibrary("Wintrust.dll");
3520 if (hDll == NULL)
3521 {
3522 return false;
3523 }
3524
3525 _WinVerifyTrust =
3526 (LONG (__stdcall *)(HWND,GUID *,LPVOID))
3527 GetProcAddress(hDll, "WinVerifyTrust");
3528 if (_WinVerifyTrust == NULL)
3529 {
3530 FreeLibrary(hDll);
3531 return false;
3532 }
3533 else
3534 {
3535 GUID action_id = WINTRUST_ACTION_GENERIC_VERIFY_V2;
3536 WINTRUST_FILE_INFO file;
3537 WINTRUST_DATA data;
3538
3539 Zero(&file, sizeof(file));
3540 file.cbStruct = sizeof(file);
3541 file.pcwszFilePath = tmp;
3542
3543 Zero(&data, sizeof(data));
3544 data.cbStruct = sizeof(data);
3545 data.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
3546 data.dwUIChoice = (hWnd != NULL ? WTD_UI_NOGOOD : WTD_UI_NONE);
3547 data.dwProvFlags = WTD_REVOCATION_CHECK_CHAIN;
3548 data.dwUnionChoice = WTD_CHOICE_FILE;
3549 data.pFile = &file;
3550
3551 ret = _WinVerifyTrust(hWnd, &action_id, &data);
3552
3553 if (ret == ERROR_SUCCESS && danger != NULL)
3554 {
3555 if (hWnd != NULL)
3556 {
3557 if (MsCheckFileDigitalSignatureW(NULL, name, NULL) == false)
3558 {
3559 // It's a dangerous file, but the user had to select the [OK]
3560 *danger = true;
3561 }
3562 }
3563 }
3564 }
3565
3566 FreeLibrary(hDll);
3567
3568 if (ret != ERROR_SUCCESS)
3569 {
3570 return false;
3571 }
3572
3573 return true;
3574 }
3575
3576 // Enable or disable the WoW64 redirection
MsSetWow64FileSystemRedirectionEnable(bool enable)3577 void MsSetWow64FileSystemRedirectionEnable(bool enable)
3578 {
3579 if (MsIs64BitWindows() == false)
3580 {
3581 return;
3582 }
3583
3584 if (ms->nt->Wow64EnableWow64FsRedirection == NULL)
3585 {
3586 return;
3587 }
3588
3589 ms->nt->Wow64EnableWow64FsRedirection(enable ? 1 : 0);
3590 }
3591
3592 // Disable the WoW64 redirection
MsDisableWow64FileSystemRedirection()3593 void *MsDisableWow64FileSystemRedirection()
3594 {
3595 void *p = NULL;
3596 if (MsIs64BitWindows() == false)
3597 {
3598 return NULL;
3599 }
3600
3601 if (ms->nt->Wow64DisableWow64FsRedirection == NULL ||
3602 ms->nt->Wow64RevertWow64FsRedirection == NULL)
3603 {
3604 return NULL;
3605 }
3606
3607 if (ms->nt->Wow64DisableWow64FsRedirection(&p) == false)
3608 {
3609 return NULL;
3610 }
3611
3612 if (p == NULL)
3613 {
3614 p = (void *)0x12345678;
3615 }
3616
3617 return p;
3618 }
3619
3620 // Restore the WoW64 redirection
MsRestoreWow64FileSystemRedirection(void * p)3621 void MsRestoreWow64FileSystemRedirection(void *p)
3622 {
3623 // Validate arguments
3624 if (p == NULL)
3625 {
3626 return;
3627 }
3628 if (p == (void *)0x12345678)
3629 {
3630 p = NULL;
3631 }
3632 if (MsIs64BitWindows() == false)
3633 {
3634 return;
3635 }
3636
3637 if (ms->nt->Wow64DisableWow64FsRedirection == NULL ||
3638 ms->nt->Wow64RevertWow64FsRedirection == NULL)
3639 {
3640 return;
3641 }
3642
3643 ms->nt->Wow64RevertWow64FsRedirection(p);
3644 }
3645
3646 // Get whether the x64 version of Windows is currently running
MsIsX64()3647 bool MsIsX64()
3648 {
3649 SYSTEM_INFO info;
3650
3651 if (MsIs64BitWindows() == false)
3652 {
3653 return false;
3654 }
3655 if (ms->nt->GetNativeSystemInfo == NULL)
3656 {
3657 return false;
3658 }
3659
3660 Zero(&info, sizeof(info));
3661 ms->nt->GetNativeSystemInfo(&info);
3662
3663 if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
3664 {
3665 return true;
3666 }
3667
3668 return false;
3669 }
3670
3671 // Get whether the IA64 version of Windows is currently running
MsIsIA64()3672 bool MsIsIA64()
3673 {
3674 if (MsIs64BitWindows() == false)
3675 {
3676 return false;
3677 }
3678
3679 if (MsIsX64())
3680 {
3681 return false;
3682 }
3683
3684 return true;
3685 }
3686
3687 // Acquisition whether it's a 64bit Windows
MsIs64BitWindows()3688 bool MsIs64BitWindows()
3689 {
3690 if (Is64())
3691 {
3692 return true;
3693 }
3694 else
3695 {
3696 if (MsIsNt() == false)
3697 {
3698 return false;
3699 }
3700 else
3701 {
3702 if (ms == NULL || ms->nt == NULL)
3703 {
3704 return false;
3705 }
3706
3707 if (ms->nt->IsWow64Process == NULL)
3708 {
3709 return false;
3710 }
3711 else
3712 {
3713 bool b = false;
3714 if (ms->nt->IsWow64Process(GetCurrentProcess(), &b) == false)
3715 {
3716 return false;
3717 }
3718 return b;
3719 }
3720 }
3721 }
3722 }
3723
3724 // Windows Firewall registration
MsRegistWindowsFirewallEx2(char * title,char * exe,char * dir)3725 void MsRegistWindowsFirewallEx2(char *title, char *exe, char *dir)
3726 {
3727 char tmp[MAX_PATH];
3728 // Validate arguments
3729 if (title == NULL || exe == NULL)
3730 {
3731 return;
3732 }
3733 if (dir == NULL || IsEmptyStr(dir))
3734 {
3735 dir = MsGetExeDirName();
3736 }
3737
3738 ConbinePath(tmp, sizeof(tmp), dir, exe);
3739
3740 if (IsFileExists(tmp) == false)
3741 {
3742 return;
3743 }
3744
3745 MsRegistWindowsFirewallEx(title, tmp);
3746 }
MsRegistWindowsFirewallEx(char * title,char * exe)3747 void MsRegistWindowsFirewallEx(char *title, char *exe)
3748 {
3749 char *data =
3750 "Option Explicit\r\nConst NET_FW_PROFILE_DOMAIN = 0\r\nConst NET_FW_PROFILE_STANDARD = 1\r\n"
3751 "Const NET_FW_SCOPE_ALL = 0\r\nConst NET_FW_IP_VERSION_ANY = 2\r\nDim fwMgr\r\n"
3752 "Set fwMgr = CreateObject(\"HNetCfg.FwMgr\")\r\nDim profile\r\n"
3753 "Set profile = fwMgr.LocalPolicy.CurrentProfile\r\nDim app\r\n"
3754 "Set app = CreateObject(\"HNetCfg.FwAuthorizedApplication\")\r\n"
3755 "app.ProcessImageFileName = \"$PATH$\"\r\napp.Name = \"$TITLE$\"\r\n"
3756 "app.Scope = NET_FW_SCOPE_ALL\r\napp.IpVersion = NET_FW_IP_VERSION_ANY\r\n"
3757 "app.Enabled = TRUE\r\nOn Error Resume Next\r\nprofile.AuthorizedApplications."
3758 "Add app\r\n";
3759 char *tmp;
3760 UINT tmp_size;
3761 char filename[MAX_PATH];
3762 char cscript[MAX_PATH];
3763 char arg[MAX_PATH];
3764 UINT ostype;
3765 IO *o;
3766 char hash[MAX_PATH];
3767 UCHAR hashbin[SHA1_SIZE];
3768 UCHAR file_hash_bin[SHA1_SIZE];
3769 char file_hash_str[MAX_SIZE];
3770 // Validate arguments
3771 if (title == NULL || exe == NULL)
3772 {
3773 return;
3774 }
3775
3776 // OS check (This Is not performed except Windows XP, Windows Server 2003, Windows Vista or later)
3777 ostype = GetOsInfo()->OsType;
3778 if (OS_IS_WINDOWS_NT(ostype) == false)
3779 {
3780 return;
3781 }
3782 if (MsIsAdmin() == false)
3783 {
3784 return;
3785 }
3786
3787 if (MsIsVista())
3788 {
3789 data = "Option Explicit\r\n\r\nConst PROFILES_ALL = 7\r\nConst NET_FW_ACTION_ALLOWNET_FW_ACTION_ALLOW = 1\r\n"
3790 "\r\nDim policy2\r\nDim rules\r\nDim new_rule\r\n\r\nOn Error Resume Next\r\n\r\n"
3791 "Set policy2 = CreateObject(\"HNetCfg.FwPolicy2\")\r\nSet rules = policy2.Rules\r\n"
3792 "Set new_rule = CreateObject(\"HNetCfg.FWRule\")\r\nnew_rule.Name = \"$TITLE$\"\r\n"
3793 "new_rule.Description = \"$TITLE$\"\r\nnew_rule.ApplicationName = \"$PATH$\"\r\n"
3794 "new_rule.Enabled = TRUE\r\nnew_rule.Profiles = PROFILES_ALL\r\nnew_rule.Action = "
3795 "NET_FW_ACTION_ALLOWNET_FW_ACTION_ALLOW\r\nrules.Add new_rule\r\n\r\n";
3796 }
3797
3798 tmp_size = StrLen(data) * 4;
3799 tmp = ZeroMalloc(tmp_size);
3800
3801 HashSha1(hashbin, exe, StrLen(exe));
3802 BinToStr(hash, sizeof(hash), hashbin, 6);
3803
3804 ReplaceStrEx(tmp, tmp_size, data, "$TITLE$", title, false);
3805 ReplaceStrEx(tmp, tmp_size, tmp, "$PATH$", exe, false);
3806
3807 HashSha1(file_hash_bin, tmp, StrLen(tmp));
3808 BinToStr(file_hash_str, sizeof(file_hash_str), file_hash_bin, sizeof(file_hash_bin));
3809
3810 if (MsIsVista() == false || MsRegReadIntEx2(REG_LOCAL_MACHINE, SOFTETHER_FW_SCRIPT_HASH, file_hash_str, false, true) == 0)
3811 {
3812 Format(filename, sizeof(filename), "%s\\winfire_%s.vbs", MsGetMyTempDir(), hash);
3813 o = FileCreate(filename);
3814 FileWrite(o, tmp, StrLen(tmp));
3815 FileClose(o);
3816
3817 Format(cscript, sizeof(cscript), "%s\\cscript.exe", MsGetSystem32Dir());
3818 Format(arg, sizeof(arg), "\"%s\"", filename);
3819
3820 if (Run(cscript, arg, true, false))
3821 {
3822 MsRegWriteIntEx2(REG_LOCAL_MACHINE, SOFTETHER_FW_SCRIPT_HASH, file_hash_str, 1, false, true);
3823 }
3824
3825 Debug("cscript %s\n", arg);
3826 }
3827
3828 Free(tmp);
3829 }
3830
3831 // Run driver installer for Vista
MsExecDriverInstaller(char * arg)3832 bool MsExecDriverInstaller(char *arg)
3833 {
3834 wchar_t tmp[MAX_PATH];
3835 wchar_t hamcore_dst[MAX_PATH];
3836 wchar_t hamcore_src[MAX_PATH];
3837 wchar_t lang_config_src[MAX_PATH];
3838 wchar_t lang_config_dst[MAX_PATH];
3839 HANDLE h;
3840 UINT retcode;
3841 SHELLEXECUTEINFOW info;
3842 wchar_t *src_exe;
3843 wchar_t *arg_w;
3844 // Validate arguments
3845 if (arg == NULL)
3846 {
3847 return false;
3848 }
3849
3850 UniFormat(hamcore_dst, sizeof(hamcore_dst), L"%s\\hamcore.se2", MsGetMyTempDirW());
3851 UniFormat(hamcore_src, sizeof(hamcore_src), L"%s\\hamcore.se2", MsGetExeDirNameW());
3852
3853 // Extract the File
3854 src_exe = VISTA_DRIVER_INSTALLER_SRC;
3855
3856 if (MsIsX64())
3857 {
3858 src_exe = VISTA_DRIVER_INSTALLER_SRC_X64;
3859 }
3860 if (MsIsIA64())
3861 {
3862 src_exe = VISTA_DRIVER_INSTALLER_SRC_IA64;
3863 }
3864
3865 UniFormat(tmp, sizeof(tmp), VISTA_DRIVER_INSTALLER_DST, MsGetMyTempDirW());
3866
3867 if (FileCopyW(src_exe, tmp) == false)
3868 {
3869 return false;
3870 }
3871
3872 if (FileCopyW(hamcore_src, hamcore_dst) == false)
3873 {
3874 return false;
3875 }
3876
3877 ConbinePathW(lang_config_src, sizeof(lang_config_src), MsGetExeDirNameW(), L"lang.config");
3878 ConbinePathW(lang_config_dst, sizeof(lang_config_dst), MsGetMyTempDirW(), L"lang.config");
3879 FileCopyW(lang_config_src, lang_config_dst);
3880
3881 arg_w = CopyStrToUni(arg);
3882
3883 // Run
3884 Zero(&info, sizeof(info));
3885 info.cbSize = sizeof(info);
3886 info.lpVerb = L"open";
3887 info.lpFile = tmp;
3888 info.fMask = SEE_MASK_NOCLOSEPROCESS;
3889 info.lpParameters = arg_w;
3890 info.nShow = SW_SHOWNORMAL;
3891 if (ShellExecuteExW(&info) == false)
3892 {
3893 Free(arg_w);
3894 return false;
3895 }
3896
3897 Free(arg_w);
3898
3899 h = info.hProcess;
3900 retcode = 1;
3901
3902 while (true)
3903 {
3904 // Wait for completion
3905 WaitForSingleObject(h, INFINITE);
3906
3907 // Get the exit code
3908 retcode = 1;
3909 if (GetExitCodeProcess(h, &retcode) == false)
3910 {
3911 break;
3912 }
3913
3914 if (retcode != STILL_ACTIVE)
3915 {
3916 break;
3917 }
3918 }
3919
3920 CloseHandle(h);
3921
3922 if (retcode & 1)
3923 {
3924 return false;
3925 }
3926
3927 return true;
3928 }
3929
3930 // Get the locale of the current thread
MsGetThreadLocale()3931 UINT MsGetThreadLocale()
3932 {
3933 return (UINT)GetThreadLocale();
3934 }
3935
3936 // Set the width of the current console
MsSetConsoleWidth(UINT size)3937 UINT MsSetConsoleWidth(UINT size)
3938 {
3939 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
3940 CONSOLE_SCREEN_BUFFER_INFO info;
3941 COORD c;
3942 UINT old_x, old_y;
3943 // Validate arguments
3944 if (size == 0)
3945 {
3946 return 0;
3947 }
3948 if (h == INVALID_HANDLE_VALUE)
3949 {
3950 return 0;
3951 }
3952
3953 Zero(&info, sizeof(info));
3954 if (GetConsoleScreenBufferInfo(h, &info) == false)
3955 {
3956 return 0;
3957 }
3958
3959 old_x = info.dwSize.X;
3960 old_y = info.dwSize.Y;
3961
3962 c.X = size;
3963 c.Y = old_y;
3964
3965 SetConsoleScreenBufferSize(h, c);
3966
3967 return old_x;
3968 }
3969
3970 // Get the width of the current console
MsGetConsoleWidth()3971 UINT MsGetConsoleWidth()
3972 {
3973 HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
3974 CONSOLE_SCREEN_BUFFER_INFO info;
3975
3976 if (h == INVALID_HANDLE_VALUE)
3977 {
3978 return 80;
3979 }
3980
3981 Zero(&info, sizeof(info));
3982 if (GetConsoleScreenBufferInfo(h, &info) == false)
3983 {
3984 return 80;
3985 }
3986
3987 return info.dwSize.X;
3988 }
3989
3990 // Disable the MS-IME
MsDisableIme()3991 bool MsDisableIme()
3992 {
3993 HINSTANCE h;
3994 bool ret = false;
3995 char dll_name[MAX_PATH];
3996 BOOL (WINAPI *_ImmDisableIME)(DWORD);
3997
3998 Format(dll_name, sizeof(dll_name), "%s\\imm32.dll", MsGetSystem32Dir());
3999 h = MsLoadLibrary(dll_name);
4000 if (h == NULL)
4001 {
4002 return false;
4003 }
4004
4005 _ImmDisableIME = (BOOL (__stdcall *)(DWORD))GetProcAddress(h, "ImmDisableIME");
4006
4007 if (_ImmDisableIME != NULL)
4008 {
4009 ret = _ImmDisableIME(-1);
4010 }
4011
4012 FreeLibrary(h);
4013
4014 return ret;
4015 }
4016
4017 // Display the current time
MsPrintTick()4018 void MsPrintTick()
4019 {
4020 UINT tick = timeGetTime();
4021 static UINT tick_init = 0;
4022 if (tick_init == 0)
4023 {
4024 tick_init = tick;
4025 tick = 0;
4026 }
4027 else
4028 {
4029 tick -= tick_init;
4030 }
4031
4032 printf("[%u]\n", tick);
4033 }
4034
4035 // LoadLibrary compatible for hamcore (Read as a data file)
MsLoadLibraryAsDataFileW(wchar_t * name)4036 void *MsLoadLibraryAsDataFileW(wchar_t *name)
4037 {
4038 BUF *b;
4039 wchar_t tmp_dll_name[MAX_SIZE];
4040 char hash_str[MAX_SIZE];
4041 UCHAR hash[SHA1_SIZE];
4042 // Validate arguments
4043 if (name == NULL)
4044 {
4045 return NULL;
4046 }
4047
4048 Hash(hash, name, UniStrLen(name), true);
4049
4050 BinToStr(hash_str, sizeof(hash_str), hash, 4);
4051
4052 UniFormat(tmp_dll_name, sizeof(tmp_dll_name), L"%s\\%S.dll", MsGetMyTempDirW(), hash_str);
4053
4054 if (IsFileExistsW(tmp_dll_name) == false)
4055 {
4056 b = ReadDumpW(name);
4057 if (b == NULL)
4058 {
4059 return NULL;
4060 }
4061
4062 DumpBufW(b, tmp_dll_name);
4063 FreeBuf(b);
4064 }
4065
4066 return LoadLibraryExW(tmp_dll_name, NULL, LOAD_LIBRARY_AS_DATAFILE);
4067 }
MsLoadLibraryAsDataFile(char * name)4068 void *MsLoadLibraryAsDataFile(char *name)
4069 {
4070 wchar_t name_w[MAX_SIZE];
4071 // Validate arguments
4072 if (name == NULL)
4073 {
4074 return NULL;
4075 }
4076
4077 StrToUni(name_w, sizeof(name_w), name);
4078
4079 return MsLoadLibraryAsDataFileW(name_w);
4080 }
4081
4082 // Simple LoadLibaray
MsLoadLibraryRawW(wchar_t * name)4083 void *MsLoadLibraryRawW(wchar_t *name)
4084 {
4085 // Validate arguments
4086 if (name == NULL)
4087 {
4088 return NULL;
4089 }
4090
4091 if (MsIsNt())
4092 {
4093 return LoadLibraryW(name);
4094 }
4095 else
4096 {
4097 char tmp[MAX_PATH];
4098
4099 UniToStr(tmp, sizeof(tmp), name);
4100
4101 return LoadLibraryA(tmp);
4102 }
4103 }
4104
4105 // LoadLibrary (compatible for Hamcore)
MsLoadLibraryW(wchar_t * name)4106 void *MsLoadLibraryW(wchar_t *name)
4107 {
4108 BUF *b;
4109 wchar_t tmp_dll_name[MAX_SIZE];
4110 char hash_str[MAX_SIZE];
4111 UCHAR hash[SHA1_SIZE];
4112 // Validate arguments
4113 if (name == NULL)
4114 {
4115 return NULL;
4116 }
4117
4118 Hash(hash, name, UniStrSize(name), true);
4119
4120 BinToStr(hash_str, sizeof(hash_str), hash, 4);
4121
4122 UniFormat(tmp_dll_name, sizeof(tmp_dll_name), L"%s\\%S.dll", MsGetMyTempDirW(), hash_str);
4123
4124 if (IsFileExistsW(tmp_dll_name) == false)
4125 {
4126 b = ReadDumpW(name);
4127 if (b == NULL)
4128 {
4129 return NULL;
4130 }
4131
4132 DumpBufW(b, tmp_dll_name);
4133 FreeBuf(b);
4134 }
4135
4136 if (IsNt())
4137 {
4138 return LoadLibraryW(tmp_dll_name);
4139 }
4140 else
4141 {
4142 char tmp_dll_name_a[MAX_SIZE];
4143 HINSTANCE ret;
4144
4145 UniToStr(tmp_dll_name_a, sizeof(tmp_dll_name_a), tmp_dll_name);
4146
4147 ret = LoadLibraryA(tmp_dll_name_a);
4148
4149 return ret;
4150 }
4151 }
MsLoadLibrary(char * name)4152 void *MsLoadLibrary(char *name)
4153 {
4154 wchar_t name_w[MAX_SIZE];
4155 // Validate arguments
4156 if (name == NULL)
4157 {
4158 return NULL;
4159 }
4160
4161 StrToUni(name_w, sizeof(name_w), name);
4162
4163 return MsLoadLibraryW(name_w);
4164 }
4165
4166 // Release of the library
MsFreeLibrary(void * h)4167 void MsFreeLibrary(void *h)
4168 {
4169 // Validate arguments
4170 if (h == NULL)
4171 {
4172 return;
4173 }
4174
4175 FreeLibrary(h);
4176 }
4177
4178 // Get the function pointer in the DLL
MsGetProcAddress(void * h,char * name)4179 void *MsGetProcAddress(void *h, char *name)
4180 {
4181 // Validate arguments
4182 if (h == NULL || name == NULL)
4183 {
4184 return NULL;
4185 }
4186
4187 return (void *)GetProcAddress(h, name);
4188 }
4189
4190 // Search for the adapter by GUID
MsGetAdapterByGuid(char * guid)4191 MS_ADAPTER *MsGetAdapterByGuid(char *guid)
4192 {
4193 MS_ADAPTER_LIST *o;
4194 MS_ADAPTER *ret = NULL;
4195 // Validate arguments
4196 if (guid == NULL)
4197 {
4198 return NULL;
4199 }
4200
4201 o = MsCreateAdapterList();
4202 if (o == NULL)
4203 {
4204 return NULL;
4205 }
4206
4207 ret = MsGetAdapterByGuidFromList(o, guid);
4208
4209 MsFreeAdapterList(o);
4210
4211 return ret;
4212 }
MsGetAdapterByGuidFromList(MS_ADAPTER_LIST * o,char * guid)4213 MS_ADAPTER *MsGetAdapterByGuidFromList(MS_ADAPTER_LIST *o, char *guid)
4214 {
4215 MS_ADAPTER *ret = NULL;
4216 UINT i;
4217 // Validate arguments
4218 if (o == NULL || guid == NULL)
4219 {
4220 return NULL;
4221 }
4222
4223 for (i = 0;i < o->Num;i++)
4224 {
4225 if (StrCmpi(o->Adapters[i]->Guid, guid) == 0)
4226 {
4227 ret = MsCloneAdapter(o->Adapters[i]);
4228 break;
4229 }
4230 }
4231
4232 return ret;
4233 }
4234
4235 // Get a single adapter
MsGetAdapter(char * title)4236 MS_ADAPTER *MsGetAdapter(char *title)
4237 {
4238 MS_ADAPTER_LIST *o;
4239 MS_ADAPTER *ret = NULL;
4240 UINT i;
4241 // Validate arguments
4242 if (title == NULL)
4243 {
4244 return NULL;
4245 }
4246
4247 o = MsCreateAdapterList();
4248 if (o == NULL)
4249 {
4250 return NULL;
4251 }
4252
4253 for (i = 0;i < o->Num;i++)
4254 {
4255 if (StrCmpi(o->Adapters[i]->Title, title) == 0)
4256 {
4257 ret = MsCloneAdapter(o->Adapters[i]);
4258 break;
4259 }
4260 }
4261
4262 MsFreeAdapterList(o);
4263
4264 return ret;
4265 }
4266
4267 // 32-bit overflow checking
4268 #define CHECK_32BIT_OVERFLOW(old_value, new_value) \
4269 { \
4270 if ((old_value) > (new_value)) \
4271 { \
4272 (new_value) += ((UINT64)4294967296ULL); \
4273 } \
4274 }
4275
4276 // Get the TCP/IP information of the specified adapter
MsGetAdapterTcpIpInformation(MS_ADAPTER * a)4277 void MsGetAdapterTcpIpInformation(MS_ADAPTER *a)
4278 {
4279 IP_ADAPTER_INFO *info, *info_top;
4280 UINT info_size;
4281 UINT ret;
4282 // Validate arguments
4283 if (a == NULL)
4284 {
4285 return;
4286 }
4287
4288 if (w32net->GetAdaptersInfo == NULL)
4289 {
4290 return;
4291 }
4292
4293 info_top = ZeroMalloc(sizeof(IP_ADAPTER_INFO));
4294 info_size = sizeof(IP_ADAPTER_INFO);
4295
4296 ret = w32net->GetAdaptersInfo(info_top, &info_size);
4297 if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW)
4298 {
4299 Free(info_top);
4300 info_size *= 2;
4301 info_top = ZeroMalloc(info_size);
4302
4303 if (w32net->GetAdaptersInfo(info_top, &info_size) != NO_ERROR)
4304 {
4305 Free(info_top);
4306 return;
4307 }
4308 }
4309 else if (ret != NO_ERROR)
4310 {
4311 Free(info_top);
4312 return;
4313 }
4314
4315 // Search for their own entry
4316 info = info_top;
4317
4318 while (info != NULL)
4319 {
4320 if (info->Index == a->Index)
4321 {
4322 IP_ADDR_STRING *s;
4323
4324 // IP address
4325 a->NumIpAddress = 0;
4326 s = &info->IpAddressList;
4327 while (s != NULL)
4328 {
4329 if (a->NumIpAddress < MAX_MS_ADAPTER_IP_ADDRESS)
4330 {
4331 StrToIP(&a->IpAddresses[a->NumIpAddress], s->IpAddress.String);
4332 StrToIP(&a->SubnetMasks[a->NumIpAddress], s->IpMask.String);
4333 a->NumIpAddress++;
4334 }
4335 s = s->Next;
4336 }
4337
4338 // Gateway
4339 a->NumGateway = 0;
4340 s = &info->GatewayList;
4341 while (s != NULL)
4342 {
4343 if (a->NumGateway < MAX_MS_ADAPTER_IP_ADDRESS)
4344 {
4345 StrToIP(&a->Gateways[a->NumGateway], s->IpAddress.String);
4346 a->NumGateway++;
4347 }
4348 s = s->Next;
4349 }
4350
4351 // DHCP Server
4352 a->UseDhcp = (info->DhcpEnabled == 0 ? false : true);
4353 if (a->UseDhcp)
4354 {
4355 SYSTEMTIME st;
4356
4357 StrToIP(&a->DhcpServer, info->DhcpServer.IpAddress.String);
4358 TimeToSystem(&st, info->LeaseObtained);
4359 a->DhcpLeaseStart = SystemToUINT64(&st);
4360
4361 TimeToSystem(&st, info->LeaseExpires);
4362 a->DhcpLeaseExpires = SystemToUINT64(&st);
4363 }
4364
4365 // WINS server
4366 a->UseWins = info->HaveWins;
4367 if (a->UseWins)
4368 {
4369 StrToIP(&a->PrimaryWinsServer, info->PrimaryWinsServer.IpAddress.String);
4370 StrToIP(&a->SecondaryWinsServer, info->SecondaryWinsServer.IpAddress.String);
4371 }
4372
4373 StrCpy(a->Guid, sizeof(a->Guid), info->AdapterName);
4374
4375 a->Info = true;
4376
4377 break;
4378 }
4379
4380 info = info->Next;
4381 }
4382
4383 Free(info_top);
4384 }
4385
4386 // Generation of adapter list
MsCreateAdapterList()4387 MS_ADAPTER_LIST *MsCreateAdapterList()
4388 {
4389 return MsCreateAdapterListEx(false);
4390 }
MsCreateAdapterListEx(bool no_info)4391 MS_ADAPTER_LIST *MsCreateAdapterListEx(bool no_info)
4392 {
4393 MS_ADAPTER_LIST *ret;
4394
4395 if (no_info)
4396 {
4397 ret = MsCreateAdapterListInnerEx(true);
4398
4399 return ret;
4400 }
4401
4402 Lock(lock_adapter_list);
4403 {
4404 MS_ADAPTER_LIST *old = last_adapter_list;
4405 UINT i;
4406
4407 // Fetch a new adapter list
4408 ret = MsCreateAdapterListInner();
4409
4410 if (ret == NULL)
4411 {
4412 Unlock(lock_adapter_list);
4413 return NULL;
4414 }
4415
4416 // Check whether the previously acquired item exists for each entry
4417 // in the list of adapters have been taken
4418 for (i = 0;i < ret->Num;i++)
4419 {
4420 UINT j;
4421 for (j = 0;j < old->Num;j++)
4422 {
4423 MS_ADAPTER *o = old->Adapters[j];
4424 MS_ADAPTER *n = ret->Adapters[i];
4425
4426 if (StrCmpi(o->Title, n->Title) == 0)
4427 {
4428 // If the value of older item is small, increment it
4429 CHECK_32BIT_OVERFLOW(o->RecvBytes, n->RecvBytes);
4430 CHECK_32BIT_OVERFLOW(o->RecvPacketsBroadcast, n->RecvPacketsBroadcast);
4431 CHECK_32BIT_OVERFLOW(o->RecvPacketsUnicast, n->RecvPacketsUnicast);
4432 CHECK_32BIT_OVERFLOW(o->SendBytes, n->SendBytes);
4433 CHECK_32BIT_OVERFLOW(o->SendPacketsBroadcast, n->SendPacketsBroadcast);
4434 CHECK_32BIT_OVERFLOW(o->SendPacketsUnicast, n->SendPacketsUnicast);
4435 break;
4436 }
4437 }
4438 }
4439
4440 // Release the old adapter list
4441 MsFreeAdapterList(old);
4442
4443 // Save a clone of the adapter list that newly acquired
4444 last_adapter_list = MsCloneAdapterList(ret);
4445 }
4446 Unlock(lock_adapter_list);
4447
4448 return ret;
4449 }
4450
4451 // Initialization of the adapter module list
MsInitAdapterListModule()4452 void MsInitAdapterListModule()
4453 {
4454 lock_adapter_list = NewLock(NULL);
4455
4456 last_adapter_list = MsCreateAdapterListInner();
4457 }
4458
4459 // Release of the adapter module list
MsFreeAdapterListModule()4460 void MsFreeAdapterListModule()
4461 {
4462 if (last_adapter_list != NULL)
4463 {
4464 MsFreeAdapterList(last_adapter_list);
4465 last_adapter_list = NULL;
4466 }
4467
4468 DeleteLock(lock_adapter_list);
4469 lock_adapter_list = NULL;
4470 }
4471
4472 // Clone the adapter list
MsCloneAdapterList(MS_ADAPTER_LIST * o)4473 MS_ADAPTER_LIST *MsCloneAdapterList(MS_ADAPTER_LIST *o)
4474 {
4475 MS_ADAPTER_LIST *ret;
4476 UINT i;
4477 // Validate arguments
4478 if (o == NULL)
4479 {
4480 return NULL;
4481 }
4482
4483 ret = ZeroMalloc(sizeof(MS_ADAPTER_LIST));
4484 ret->Num = o->Num;
4485 ret->Adapters = ZeroMalloc(sizeof(MS_ADAPTER *) * ret->Num);
4486
4487 for (i = 0;i < ret->Num;i++)
4488 {
4489 ret->Adapters[i] = ZeroMalloc(sizeof(MS_ADAPTER));
4490 Copy(ret->Adapters[i], o->Adapters[i], sizeof(MS_ADAPTER));
4491 }
4492
4493 return ret;
4494 }
4495
4496 // Clone the adapter
MsCloneAdapter(MS_ADAPTER * a)4497 MS_ADAPTER *MsCloneAdapter(MS_ADAPTER *a)
4498 {
4499 MS_ADAPTER *ret;
4500 // Validate arguments
4501 if (a == NULL)
4502 {
4503 return NULL;
4504 }
4505
4506 ret = ZeroMalloc(sizeof(MS_ADAPTER));
4507 Copy(ret, a, sizeof(MS_ADAPTER));
4508
4509 return ret;
4510 }
4511
4512 // Creating an adapters list
MsCreateAdapterListInner()4513 MS_ADAPTER_LIST *MsCreateAdapterListInner()
4514 {
4515 return MsCreateAdapterListInnerEx(false);
4516 }
MsCreateAdapterListInnerEx(bool no_info)4517 MS_ADAPTER_LIST *MsCreateAdapterListInnerEx(bool no_info)
4518 {
4519 LIST *o;
4520 UINT i;
4521 UINT retcode;
4522 MIB_IFTABLE *table;
4523 UINT table_size = sizeof(MIB_IFTABLE);
4524 MS_ADAPTER_LIST *ret;
4525
4526 if (w32net->GetIfTable2 != NULL && w32net->FreeMibTable != NULL)
4527 {
4528 return MsCreateAdapterListInnerExVista(no_info);
4529 }
4530
4531 if (w32net->GetIfTable == NULL)
4532 {
4533 return ZeroMalloc(sizeof(MS_ADAPTER_LIST));
4534 }
4535
4536 table = ZeroMalloc(table_size);
4537
4538 retcode = w32net->GetIfTable(table, &table_size, TRUE);
4539 if (retcode == ERROR_INSUFFICIENT_BUFFER || retcode == ERROR_BUFFER_OVERFLOW)
4540 {
4541 Free(table);
4542 table_size *= 2;
4543 table = ZeroMalloc(table_size);
4544 if (w32net->GetIfTable(table, &table_size, TRUE) != NO_ERROR)
4545 {
4546 Free(table);
4547 return ZeroMalloc(sizeof(MS_ADAPTER_LIST));
4548 }
4549 }
4550 else if (retcode != NO_ERROR)
4551 {
4552 Free(table);
4553 return ZeroMalloc(sizeof(MS_ADAPTER_LIST));
4554 }
4555
4556 o = NewListFast(NULL);
4557
4558 for (i = 0;i < table->dwNumEntries;i++)
4559 {
4560 MIB_IFROW *r = &table->table[i];
4561 char title[MAX_PATH];
4562 UINT num = 0;
4563 MS_ADAPTER *a;
4564 UINT j;
4565
4566 //if (r->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || r->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
4567 {
4568 //if (r->dwType & IF_TYPE_ETHERNET_CSMACD)
4569 {
4570 for (j = 1;;j++)
4571 {
4572 UINT k;
4573 bool exists;
4574 if (j == 1)
4575 {
4576 StrCpy(title, sizeof(title), (char *)r->bDescr);
4577 }
4578 else
4579 {
4580 Format(title, sizeof(title), "%s (%u)", (char *)r->bDescr, j);
4581 }
4582
4583 exists = false;
4584
4585 for (k = 0;k < LIST_NUM(o);k++)
4586 {
4587 MS_ADAPTER *a = LIST_DATA(o, k);
4588
4589 if (StrCmpi(a->Title, title) == 0)
4590 {
4591 exists = true;
4592 break;
4593 }
4594 }
4595
4596 if (exists == false)
4597 {
4598 break;
4599 }
4600 }
4601
4602 a = ZeroMalloc(sizeof(MS_ADAPTER));
4603
4604 // Create an adapter information
4605 StrCpy(a->Title, sizeof(a->Title), title);
4606 StrToUni(a->TitleW, sizeof(a->TitleW), title);
4607 a->Index = r->dwIndex;
4608 a->Type = r->dwType;
4609 a->Status = r->dwOperStatus;
4610 a->Mtu = r->dwMtu;
4611 a->Speed = r->dwSpeed;
4612 a->AddressSize = MIN(sizeof(a->Address), r->dwPhysAddrLen);
4613 Copy(a->Address, r->bPhysAddr, a->AddressSize);
4614 a->RecvBytes = r->dwInOctets;
4615 a->RecvPacketsBroadcast = r->dwInNUcastPkts;
4616 a->RecvPacketsUnicast = r->dwInUcastPkts;
4617 a->SendBytes = r->dwOutOctets;
4618 a->SendPacketsBroadcast = r->dwOutNUcastPkts;
4619 a->SendPacketsUnicast = r->dwOutUcastPkts;
4620
4621 if (a->Type != IF_TYPE_ETHERNET_CSMACD)
4622 {
4623 a->IsNotEthernetLan = true;
4624 }
4625
4626 // TCP/IP information acquisition
4627 if (no_info == false)
4628 {
4629 MsGetAdapterTcpIpInformation(a);
4630 }
4631
4632 Add(o, a);
4633 }
4634 }
4635 }
4636
4637 ret = ZeroMalloc(sizeof(MS_ADAPTER_LIST));
4638 ret->Num = LIST_NUM(o);
4639 ret->Adapters = ToArray(o);
4640
4641 ReleaseList(o);
4642 Free(table);
4643
4644 return ret;
4645 }
4646
4647 // Creating an adapters list (Windows Vista version)
MsCreateAdapterListInnerExVista(bool no_info)4648 MS_ADAPTER_LIST *MsCreateAdapterListInnerExVista(bool no_info)
4649 {
4650 LIST *o;
4651 UINT i;
4652 UINT retcode;
4653 MIB_IF_TABLE2 *table;
4654 UINT table_size = sizeof(MIB_IFTABLE);
4655 MS_ADAPTER_LIST *ret;
4656
4657 if (w32net->GetIfTable2 == NULL || w32net->FreeMibTable == NULL)
4658 {
4659 return ZeroMalloc(sizeof(MS_ADAPTER_LIST));
4660 }
4661
4662 retcode = w32net->GetIfTable2(&table);
4663 if (retcode != NO_ERROR || table == NULL)
4664 {
4665 return ZeroMalloc(sizeof(MS_ADAPTER_LIST));
4666 }
4667
4668 o = NewListFast(NULL);
4669
4670 for (i = 0;i < table->NumEntries;i++)
4671 {
4672 MIB_IF_ROW2 *r = &table->Table[i];
4673 wchar_t title[MAX_PATH];
4674 UINT num = 0;
4675 MS_ADAPTER *a;
4676 UINT j;
4677
4678 //if (r->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || r->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
4679 {
4680 //if (r->dwType & IF_TYPE_ETHERNET_CSMACD)
4681 {
4682 for (j = 1;;j++)
4683 {
4684 UINT k;
4685 bool exists;
4686 if (j == 1)
4687 {
4688 UniStrCpy(title, sizeof(title), r->Description);
4689 }
4690 else
4691 {
4692 UniFormat(title, sizeof(title), L"%s (%u)", r->Description, j);
4693 }
4694
4695 exists = false;
4696
4697 for (k = 0;k < LIST_NUM(o);k++)
4698 {
4699 MS_ADAPTER *a = LIST_DATA(o, k);
4700
4701 if (UniStrCmpi(a->TitleW, title) == 0)
4702 {
4703 exists = true;
4704 break;
4705 }
4706 }
4707
4708 if (exists == false)
4709 {
4710 break;
4711 }
4712 }
4713
4714 a = ZeroMalloc(sizeof(MS_ADAPTER));
4715
4716 // Create an adapter information
4717 UniStrCpy(a->TitleW, sizeof(a->TitleW), title);
4718 UniToStr(a->Title, sizeof(a->Title), title);
4719 a->Index = r->InterfaceIndex;
4720 a->Type = r->Type;
4721 a->Status = ConvertMidStatusVistaToXp(r->OperStatus);
4722 a->Mtu = r->Mtu;
4723 a->Speed = MAX((UINT)r->TransmitLinkSpeed, (UINT)r->ReceiveLinkSpeed);
4724 a->AddressSize = MIN(sizeof(a->Address), r->PhysicalAddressLength);
4725 Copy(a->Address, r->PhysicalAddress, a->AddressSize);
4726 a->RecvBytes = r->InOctets;
4727 a->RecvPacketsBroadcast = r->InNUcastPkts;
4728 a->RecvPacketsUnicast = r->InUcastPkts;
4729 a->SendBytes = r->OutOctets;
4730 a->SendPacketsBroadcast = r->OutNUcastPkts;
4731 a->SendPacketsUnicast = r->OutUcastPkts;
4732
4733 if (r->MediaType == NdisMediumWirelessWan || r->PhysicalMediumType == NdisPhysicalMediumWirelessLan ||
4734 r->PhysicalMediumType == NdisPhysicalMediumWirelessWan || r->PhysicalMediumType == NdisPhysicalMediumWiMax ||
4735 r->Type == IF_TYPE_IEEE80211)
4736 {
4737 a->IsWireless = true;
4738 }
4739
4740 if (a->IsWireless ||
4741 r->Type != IF_TYPE_ETHERNET_CSMACD ||
4742 r->MediaType != NdisMedium802_3 ||
4743 (r->PhysicalMediumType != 0 && r->PhysicalMediumType != NdisPhysicalMedium802_3))
4744 {
4745 a->IsNotEthernetLan = true;
4746 }
4747
4748 // TCP/IP information acquisition
4749 if (no_info == false)
4750 {
4751 MsGetAdapterTcpIpInformation(a);
4752 }
4753
4754 Add(o, a);
4755 }
4756 }
4757 }
4758
4759 ret = ZeroMalloc(sizeof(MS_ADAPTER_LIST));
4760 ret->Num = LIST_NUM(o);
4761 ret->Adapters = ToArray(o);
4762
4763 ReleaseList(o);
4764 w32net->FreeMibTable(table);
4765
4766 return ret;
4767 }
4768
4769 // Convert the MIB Operational Status from Vista format to XP format
ConvertMidStatusVistaToXp(UINT st)4770 UINT ConvertMidStatusVistaToXp(UINT st)
4771 {
4772 switch (st)
4773 {
4774 case IfOperStatusUp:
4775 return MIB_IF_OPER_STATUS_CONNECTED;
4776
4777 case IfOperStatusDown:
4778 return MIB_IF_OPER_STATUS_DISCONNECTED;
4779 }
4780
4781 return MIB_IF_OPER_STATUS_NON_OPERATIONAL;
4782 }
4783
4784 // Release the adapter list
MsFreeAdapterList(MS_ADAPTER_LIST * o)4785 void MsFreeAdapterList(MS_ADAPTER_LIST *o)
4786 {
4787 UINT i;
4788 // Validate arguments
4789 if (o == NULL)
4790 {
4791 return;
4792 }
4793
4794 for (i = 0;i < o->Num;i++)
4795 {
4796 MsFreeAdapter(o->Adapters[i]);
4797 }
4798 Free(o->Adapters);
4799
4800 Free(o);
4801 }
4802
4803 // Release the adapter information
MsFreeAdapter(MS_ADAPTER * a)4804 void MsFreeAdapter(MS_ADAPTER *a)
4805 {
4806 // Validate arguments
4807 if (a == NULL)
4808 {
4809 return;
4810 }
4811
4812 Free(a);
4813 }
4814
4815 // Get the status string of the adapter
MsGetAdapterStatusStr(UINT status)4816 wchar_t *MsGetAdapterStatusStr(UINT status)
4817 {
4818 wchar_t *ret;
4819
4820 switch (status)
4821 {
4822 case MIB_IF_OPER_STATUS_NON_OPERATIONAL:
4823 ret = _UU("MS_NON_OPERATIONAL");
4824 break;
4825
4826 case MIB_IF_OPER_STATUS_UNREACHABLE:
4827 ret = _UU("MS_UNREACHABLE");
4828 break;
4829
4830 case MIB_IF_OPER_STATUS_DISCONNECTED:
4831 ret = _UU("MS_DISCONNECTED");
4832 break;
4833
4834 case MIB_IF_OPER_STATUS_CONNECTING:
4835 ret = _UU("MS_CONNECTING");
4836 break;
4837
4838 case MIB_IF_OPER_STATUS_CONNECTED:
4839 ret = _UU("MS_CONNECTED");
4840 break;
4841
4842 default:
4843 ret = _UU("MS_OPERATIONAL");
4844 break;
4845 }
4846
4847 return ret;
4848 }
4849
4850 // Get the type string of the adapter
MsGetAdapterTypeStr(UINT type)4851 wchar_t *MsGetAdapterTypeStr(UINT type)
4852 {
4853 wchar_t *ret;
4854
4855 switch (type)
4856 {
4857 case MIB_IF_TYPE_ETHERNET:
4858 ret = _UU("MS_ETHERNET");
4859 break;
4860
4861 case IF_TYPE_IEEE80211:
4862 ret = _UU("MS_WLAN");
4863 break;
4864
4865 case MIB_IF_TYPE_TOKENRING:
4866 ret = _UU("MS_TOKENRING");
4867 break;
4868
4869 case MIB_IF_TYPE_FDDI:
4870 ret = _UU("MS_FDDI");
4871 break;
4872
4873 case MIB_IF_TYPE_PPP:
4874 ret = _UU("MS_PPP");
4875 break;
4876
4877 case MIB_IF_TYPE_LOOPBACK:
4878 ret = _UU("MS_LOOPBACK");
4879 break;
4880
4881 case MIB_IF_TYPE_SLIP:
4882 ret = _UU("MS_SLIP");
4883 break;
4884
4885 default:
4886 ret = _UU("MS_OTHER");
4887 break;
4888 }
4889
4890 return ret;
4891 }
4892
4893 // Kill the process of specified EXE file name
MsKillProcessByExeName(wchar_t * name)4894 UINT MsKillProcessByExeName(wchar_t *name)
4895 {
4896 LIST *o;
4897 UINT me, i;
4898 UINT num = 0;
4899 // Validate arguments
4900 if (name == NULL)
4901 {
4902 return 0;
4903 }
4904
4905 o = MsGetProcessList();
4906 me = MsGetProcessId();
4907
4908 for (i = 0;i < LIST_NUM(o);i++)
4909 {
4910 MS_PROCESS *p = LIST_DATA(o, i);
4911 if (p->ProcessId != me)
4912 {
4913 if (UniStrCmpi(p->ExeFilenameW, name) == 0)
4914 {
4915 if (MsKillProcess(p->ProcessId))
4916 {
4917 num++;
4918 }
4919 }
4920 }
4921 }
4922
4923 MsFreeProcessList(o);
4924
4925 return num;
4926 }
4927
4928 // Terminate all instances except the EXE itself
MsKillOtherInstance()4929 void MsKillOtherInstance()
4930 {
4931 MsKillOtherInstanceEx(NULL);
4932 }
MsKillOtherInstanceEx(char * exclude_svcname)4933 void MsKillOtherInstanceEx(char *exclude_svcname)
4934 {
4935 UINT me, i;
4936 wchar_t me_path[MAX_PATH];
4937 wchar_t me_path_short[MAX_PATH];
4938 LIST *o = MsGetProcessList();
4939 UINT e_procid = 0;
4940 UINT e_procid2 = 0;
4941
4942 if (exclude_svcname != NULL)
4943 {
4944 e_procid = MsReadCallingServiceManagerProcessId(exclude_svcname, false);
4945 e_procid2 = MsReadCallingServiceManagerProcessId(exclude_svcname, true);
4946 }
4947
4948 me = MsGetProcessId();
4949
4950 MsGetCurrentProcessExeNameW(me_path, sizeof(me_path));
4951 MsGetShortPathNameW(me_path, me_path_short, sizeof(me_path_short));
4952
4953 for (i = 0;i < LIST_NUM(o);i++)
4954 {
4955 MS_PROCESS *p = LIST_DATA(o, i);
4956 if (p->ProcessId != me)
4957 {
4958 if ((e_procid == 0 || (e_procid != p->ProcessId)) && (e_procid2 == 0 || (e_procid2 != p->ProcessId)))
4959 {
4960 wchar_t tmp[MAX_PATH];
4961 MsGetShortPathNameW(p->ExeFilenameW, tmp, sizeof(tmp));
4962 if (UniStrCmpi(me_path_short, tmp) == 0)
4963 {
4964 MsKillProcess(p->ProcessId);
4965 }
4966 }
4967 }
4968 }
4969
4970 MsFreeProcessList(o);
4971 }
4972
4973 // Get the short file name
MsGetShortPathNameA(char * long_path,char * short_path,UINT short_path_size)4974 bool MsGetShortPathNameA(char *long_path, char *short_path, UINT short_path_size)
4975 {
4976 // Validate arguments
4977 if (long_path == NULL || short_path == NULL)
4978 {
4979 return false;
4980 }
4981
4982 if (GetShortPathNameA(long_path, short_path, short_path_size) == 0)
4983 {
4984 StrCpy(short_path, short_path_size, long_path);
4985 return false;
4986 }
4987
4988 return true;
4989 }
MsGetShortPathNameW(wchar_t * long_path,wchar_t * short_path,UINT short_path_size)4990 bool MsGetShortPathNameW(wchar_t *long_path, wchar_t *short_path, UINT short_path_size)
4991 {
4992 // Validate arguments
4993 if (long_path == NULL || short_path == NULL)
4994 {
4995 return false;
4996 }
4997
4998 if (IsNt() == false)
4999 {
5000 char short_path_a[MAX_SIZE];
5001 char long_path_a[MAX_SIZE];
5002 bool ret;
5003
5004 UniToStr(long_path_a, sizeof(long_path_a), long_path);
5005
5006 ret = MsGetShortPathNameA(long_path_a, short_path_a, sizeof(short_path_a));
5007
5008 StrToUni(short_path, short_path_size, short_path_a);
5009
5010 return ret;
5011 }
5012
5013 if (GetShortPathNameW(long_path, short_path, short_path_size) == 0)
5014 {
5015 UniStrCpy(short_path, short_path_size, long_path);
5016 return false;
5017 }
5018
5019 return true;
5020 }
5021
5022 // Kill the specified process
MsKillProcess(UINT id)5023 bool MsKillProcess(UINT id)
5024 {
5025 HANDLE h;
5026 // Validate arguments
5027 if (id == 0)
5028 {
5029 return false;
5030 }
5031
5032 h = OpenProcess(PROCESS_TERMINATE, FALSE, id);
5033 if (h == NULL)
5034 {
5035 return false;
5036 }
5037
5038 if (TerminateProcess(h, 0) == FALSE)
5039 {
5040 CloseHandle(h);
5041 return false;
5042 }
5043
5044 CloseHandle(h);
5045
5046 return true;
5047 }
5048
5049 // Get the current EXE file name
MsGetCurrentProcessExeName(char * name,UINT size)5050 void MsGetCurrentProcessExeName(char *name, UINT size)
5051 {
5052 UINT id;
5053 LIST *o;
5054 MS_PROCESS *p;
5055 // Validate arguments
5056 if (name == NULL)
5057 {
5058 return;
5059 }
5060
5061 id = MsGetCurrentProcessId();
5062 o = MsGetProcessList();
5063 p = MsSearchProcessById(o, id);
5064 if (p != NULL)
5065 {
5066 p = MsSearchProcessById(o, id);
5067 StrCpy(name, size, p->ExeFilename);
5068 }
5069 else
5070 {
5071 StrCpy(name, size, MsGetExeFileName());
5072 }
5073 MsFreeProcessList(o);
5074 }
MsGetCurrentProcessExeNameW(wchar_t * name,UINT size)5075 void MsGetCurrentProcessExeNameW(wchar_t *name, UINT size)
5076 {
5077 UINT id;
5078 LIST *o;
5079 MS_PROCESS *p;
5080 // Validate arguments
5081 if (name == NULL)
5082 {
5083 return;
5084 }
5085
5086 id = MsGetCurrentProcessId();
5087 o = MsGetProcessList();
5088 p = MsSearchProcessById(o, id);
5089 if (p != NULL)
5090 {
5091 p = MsSearchProcessById(o, id);
5092 UniStrCpy(name, size, p->ExeFilenameW);
5093 }
5094 else
5095 {
5096 UniStrCpy(name, size, MsGetExeFileNameW());
5097 }
5098 MsFreeProcessList(o);
5099 }
5100
5101 // Search the process by the process ID
MsSearchProcessById(LIST * o,UINT id)5102 MS_PROCESS *MsSearchProcessById(LIST *o, UINT id)
5103 {
5104 MS_PROCESS *p, t;
5105 // Validate arguments
5106 if (o == NULL)
5107 {
5108 return NULL;
5109 }
5110
5111 Zero(&t, sizeof(t));
5112 t.ProcessId = id;
5113
5114 p = Search(o, &t);
5115
5116 return p;
5117 }
5118
5119 // Compare the Process List items
MsCompareProcessList(void * p1,void * p2)5120 int MsCompareProcessList(void *p1, void *p2)
5121 {
5122 MS_PROCESS *e1, *e2;
5123 if (p1 == NULL || p2 == NULL)
5124 {
5125 return 0;
5126 }
5127 e1 = *(MS_PROCESS **)p1;
5128 e2 = *(MS_PROCESS **)p2;
5129 if (e1 == NULL || e2 == NULL)
5130 {
5131 return 0;
5132 }
5133
5134 if (e1->ProcessId > e2->ProcessId)
5135 {
5136 return 1;
5137 }
5138 else if (e1->ProcessId < e2->ProcessId)
5139 {
5140 return -1;
5141 }
5142 else
5143 {
5144 return 0;
5145 }
5146 }
5147
5148 // Display the process list
MsPrintProcessList(LIST * o)5149 void MsPrintProcessList(LIST *o)
5150 {
5151 UINT i;
5152 // Validate arguments
5153 if (o == NULL)
5154 {
5155 return;
5156 }
5157
5158 for (i = 0;i < LIST_NUM(o);i++)
5159 {
5160 MS_PROCESS *p = LIST_DATA(o, i);
5161 UniPrint(L"%-4u: %s\n", p->ProcessId, p->ExeFilenameW);
5162 }
5163 }
5164
5165 // Release of the process list
MsFreeProcessList(LIST * o)5166 void MsFreeProcessList(LIST *o)
5167 {
5168 UINT i;
5169 // Validate arguments
5170 if (o == NULL)
5171 {
5172 return;
5173 }
5174
5175 for (i = 0;i < LIST_NUM(o);i++)
5176 {
5177 MS_PROCESS *p = LIST_DATA(o, i);
5178 Free(p);
5179 }
5180
5181 ReleaseList(o);
5182 }
5183
5184 // Get the Process List (for WinNT)
MsGetProcessListNt()5185 LIST *MsGetProcessListNt()
5186 {
5187 LIST *o;
5188 UINT max = 16384;
5189 DWORD *processes;
5190 UINT needed, num;
5191 UINT i;
5192
5193 o = NewListFast(MsCompareProcessList);
5194
5195 if (ms->nt->EnumProcesses == NULL)
5196 {
5197 return o;
5198 }
5199
5200 processes = ZeroMalloc(sizeof(DWORD) * max);
5201
5202 if (ms->nt->EnumProcesses(processes, sizeof(DWORD) * max, &needed) == FALSE)
5203 {
5204 Free(processes);
5205 return NULL;
5206 }
5207
5208 num = needed / sizeof(DWORD);
5209
5210 for (i = 0;i < num;i++)
5211 {
5212 UINT id = processes[i];
5213 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
5214 false, id);
5215
5216 if (h != NULL)
5217 {
5218 HINSTANCE hInst = NULL;
5219 DWORD needed;
5220 char exe[MAX_SIZE];
5221 wchar_t exe_w[MAX_SIZE];
5222 bool ok = false;
5223 DWORD sz1, sz2;
5224
5225 sz1 = sizeof(exe) - 1;
5226 sz2 = sizeof(exe_w) / sizeof(wchar_t) - 1;
5227
5228 if (ms->nt->EnumProcessModules(h, &hInst, sizeof(hInst), &needed) == false)
5229 {
5230 hInst = NULL;
5231 }
5232
5233 if (ms->nt->GetModuleFileNameExA(h, hInst, exe, sizeof(exe) - 1) &&
5234 ms->nt->GetModuleFileNameExW(h, hInst, exe_w, sizeof(exe_w) / sizeof(wchar_t) - 1))
5235 {
5236 ok = true;
5237 }
5238 else if (ms->nt->QueryFullProcessImageNameA != NULL &&
5239 ms->nt->QueryFullProcessImageNameW != NULL &&
5240 ms->nt->QueryFullProcessImageNameA(h, 0, exe, &sz1) &&
5241 ms->nt->QueryFullProcessImageNameW(h, 0, exe_w, &sz2))
5242 {
5243 ok = true;
5244 }
5245
5246 if (ok)
5247 {
5248 MS_PROCESS *p = ZeroMalloc(sizeof(MS_PROCESS));
5249
5250 StrCpy(p->ExeFilename, sizeof(p->ExeFilename), exe);
5251 UniStrCpy(p->ExeFilenameW, sizeof(p->ExeFilenameW), exe_w);
5252 p->ProcessId = id;
5253
5254 Add(o, p);
5255 }
5256
5257 CloseHandle(h);
5258 }
5259 }
5260
5261 Sort(o);
5262
5263 Free(processes);
5264
5265 return o;
5266 }
5267
5268 // Get the Process List (for Win9x)
MsGetProcessList9x()5269 LIST *MsGetProcessList9x()
5270 {
5271 HANDLE h;
5272 LIST *o;
5273 HANDLE (WINAPI *CreateToolhelp32Snapshot)(DWORD, DWORD);
5274 BOOL (WINAPI *Process32First)(HANDLE, LPPROCESSENTRY32);
5275 BOOL (WINAPI *Process32Next)(HANDLE, LPPROCESSENTRY32);
5276
5277 CreateToolhelp32Snapshot =
5278 (HANDLE (__stdcall *)(DWORD,DWORD))
5279 GetProcAddress(ms->hKernel32, "CreateToolhelp32Snapshot");
5280 Process32First =
5281 (BOOL (__stdcall *)(HANDLE,LPPROCESSENTRY32))
5282 GetProcAddress(ms->hKernel32, "Process32First");
5283 Process32Next =
5284 (BOOL (__stdcall *)(HANDLE,LPPROCESSENTRY32))
5285 GetProcAddress(ms->hKernel32, "Process32Next");
5286
5287 o = NewListFast(MsCompareProcessList);
5288
5289 if (CreateToolhelp32Snapshot != NULL && Process32First != NULL && Process32Next != NULL)
5290 {
5291 h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
5292 if (h != INVALID_HANDLE_VALUE)
5293 {
5294 PROCESSENTRY32 e;
5295 Zero(&e, sizeof(e));
5296 e.dwSize = sizeof(e);
5297
5298 if (Process32First(h, &e))
5299 {
5300 while (true)
5301 {
5302 MS_PROCESS *p = ZeroMalloc(sizeof(MS_PROCESS));
5303 StrCpy(p->ExeFilename, sizeof(p->ExeFilename), e.szExeFile);
5304 StrToUni(p->ExeFilenameW, sizeof(p->ExeFilenameW), p->ExeFilename);
5305 p->ProcessId = e.th32ProcessID;
5306 Add(o, p);
5307 if (Process32Next(h, &e) == false)
5308 {
5309 break;
5310 }
5311 }
5312 }
5313 CloseHandle(h);
5314 }
5315 }
5316
5317 Sort(o);
5318
5319 return o;
5320 }
5321
5322 // Get the Process List
MsGetProcessList()5323 LIST *MsGetProcessList()
5324 {
5325 if (MsIsNt() == false)
5326 {
5327 // Windows 9x
5328 return MsGetProcessList9x();
5329 }
5330 else
5331 {
5332 // Windows NT, 2000, XP
5333 return MsGetProcessListNt();
5334 }
5335 }
5336
5337 // Force to run the current thread on a single CPU
MsSetThreadSingleCpu()5338 void MsSetThreadSingleCpu()
5339 {
5340 SetThreadAffinityMask(GetCurrentThread(), 1);
5341 }
5342
5343 // Playback of sound
MsPlaySound(char * name)5344 void MsPlaySound(char *name)
5345 {
5346 char tmp[MAX_SIZE];
5347 char wav[MAX_SIZE];
5348 char *temp;
5349 BUF *b;
5350 // Validate arguments
5351 if (name == NULL)
5352 {
5353 return;
5354 }
5355
5356 Format(tmp, sizeof(tmp), "|%s", name);
5357
5358 b = ReadDump(tmp);
5359 if (b == NULL)
5360 {
5361 return;
5362 }
5363
5364 temp = MsGetMyTempDir();
5365 Format(wav, sizeof(tmp), "%s\\%s", temp, name);
5366 DumpBuf(b, wav);
5367
5368 PlaySound(wav, NULL, SND_ASYNC | SND_FILENAME | SND_NODEFAULT);
5369
5370 FreeBuf(b);
5371 }
5372
5373 // Show an icon in the task tray
MsShowIconOnTray(HWND hWnd,HICON icon,wchar_t * tooltip,UINT msg)5374 bool MsShowIconOnTray(HWND hWnd, HICON icon, wchar_t *tooltip, UINT msg)
5375 {
5376 bool ret = true;
5377 // Validate arguments
5378 if (hWnd == NULL || icon == NULL)
5379 {
5380 return true;
5381 }
5382
5383 if (MsIsNt() == false)
5384 {
5385 Zero(&nid, sizeof(nid));
5386 nid.cbSize = sizeof(nid);
5387 nid.hWnd = hWnd;
5388 nid.uID = 1;
5389 nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
5390 nid.uCallbackMessage = msg;
5391 nid.hIcon = icon;
5392 UniToStr(nid.szTip, sizeof(nid.szTip), tooltip);
5393 ret = Shell_NotifyIcon(NIM_ADD, &nid);
5394 }
5395 else
5396 {
5397 Zero(&nid_nt, sizeof(nid_nt));
5398 nid_nt.cbSize = sizeof(nid_nt);
5399 nid_nt.hWnd = hWnd;
5400 nid_nt.uID = 1;
5401 nid_nt.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
5402 nid_nt.uCallbackMessage = msg;
5403 nid_nt.hIcon = icon;
5404 UniStrCpy(nid_nt.szTip, sizeof(nid_nt.szTip), tooltip);
5405
5406 ret = Shell_NotifyIconW(NIM_ADD, &nid_nt);
5407 }
5408
5409 tray_inited = true;
5410
5411 return ret;
5412 }
5413
5414 // Check whether the task tray has been initialized
MsIsTrayInited()5415 bool MsIsTrayInited()
5416 {
5417 return tray_inited;
5418 }
5419
5420 // Restore the icon in the task tray
MsRestoreIconOnTray()5421 void MsRestoreIconOnTray()
5422 {
5423 if (tray_inited == false)
5424 {
5425 return;
5426 }
5427
5428 if (MsIsNt() == false)
5429 {
5430 Shell_NotifyIcon(NIM_ADD, &nid);
5431 }
5432 else
5433 {
5434 Shell_NotifyIconW(NIM_ADD, &nid_nt);
5435 }
5436 }
5437
5438 // Change the icon in the task tray (go over!)
MsChangeIconOnTrayEx2(void * icon,wchar_t * tooltip,wchar_t * info_title,wchar_t * info,UINT info_flags)5439 void MsChangeIconOnTrayEx2(void *icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags)
5440 {
5441 MsChangeIconOnTrayEx((HICON)icon, tooltip, info_title, info, info_flags, false);
5442 }
5443
5444 // Change the icon in the task tray
MsChangeIconOnTray(HICON icon,wchar_t * tooltip)5445 void MsChangeIconOnTray(HICON icon, wchar_t *tooltip)
5446 {
5447 MsChangeIconOnTrayEx(icon, tooltip, NULL, NULL, NIIF_NONE, false);
5448 }
MsChangeIconOnTrayEx(HICON icon,wchar_t * tooltip,wchar_t * info_title,wchar_t * info,UINT info_flags,bool add)5449 bool MsChangeIconOnTrayEx(HICON icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags, bool add)
5450 {
5451 bool changed = false;
5452 bool ret = true;
5453
5454 if (tray_inited == false)
5455 {
5456 return ret;
5457 }
5458
5459 if (icon != NULL)
5460 {
5461 if (MsIsNt() == false)
5462 {
5463 if (nid.hIcon != icon)
5464 {
5465 changed = true;
5466 nid.hIcon = icon;
5467 }
5468 }
5469 else
5470 {
5471 if (nid_nt.hIcon != icon)
5472 {
5473 changed = true;
5474 nid_nt.hIcon = icon;
5475 }
5476 }
5477 }
5478
5479 if (tooltip != NULL)
5480 {
5481 if (MsIsNt() == false)
5482 {
5483 char tmp[MAX_SIZE];
5484
5485 UniToStr(tmp, sizeof(tmp), tooltip);
5486
5487 if (StrCmp(nid.szTip, tmp) != 0)
5488 {
5489 StrCpy(nid.szTip, sizeof(nid.szTip), tmp);
5490 changed = true;
5491 }
5492 }
5493 else
5494 {
5495 wchar_t tmp[MAX_SIZE];
5496
5497 UniStrCpy(tmp, sizeof(tmp), tooltip);
5498
5499 if (UniStrCmp(nid_nt.szTip, tmp) != 0)
5500 {
5501 UniStrCpy(nid_nt.szTip, sizeof(nid_nt.szTip), tmp);
5502 changed = true;
5503 }
5504 }
5505 }
5506
5507 if (info_title != NULL && info != NULL)
5508 {
5509 if (MsIsNt() == false)
5510 {
5511 char tmp1[MAX_SIZE];
5512 char tmp2[MAX_PATH];
5513
5514 UniToStr(tmp1, sizeof(tmp1), info_title);
5515 UniToStr(tmp2, sizeof(tmp2), info);
5516
5517 if (StrCmp(nid.szInfo, tmp1) != 0 ||
5518 StrCmp(nid.szInfoTitle, tmp2) != 0)
5519 {
5520 StrCpy(nid.szInfo, sizeof(nid.szInfo), tmp1);
5521 StrCpy(nid.szInfoTitle, sizeof(nid.szInfoTitle), tmp2);
5522 nid.dwInfoFlags = info_flags;
5523
5524 changed = true;
5525 }
5526 }
5527 else
5528 {
5529 wchar_t tmp1[MAX_SIZE];
5530 wchar_t tmp2[MAX_PATH];
5531
5532 UniStrCpy(tmp1, sizeof(tmp1), info_title);
5533 UniStrCpy(tmp2, sizeof(tmp2), info);
5534
5535 if (UniStrCmp(nid_nt.szInfo, tmp1) != 0 ||
5536 UniStrCmp(nid_nt.szInfoTitle, tmp2) != 0)
5537 {
5538 UniStrCpy(nid_nt.szInfo, sizeof(nid_nt.szInfo), tmp1);
5539 UniStrCpy(nid_nt.szInfoTitle, sizeof(nid_nt.szInfoTitle), tmp2);
5540 nid_nt.dwInfoFlags = info_flags;
5541
5542 changed = true;
5543 }
5544 }
5545 }
5546
5547 if (changed || add)
5548 {
5549 UINT op = (add ? NIM_ADD : NIM_MODIFY);
5550 if (MsIsNt() == false)
5551 {
5552 ret = Shell_NotifyIcon(op, &nid);
5553 }
5554 else
5555 {
5556 ret = Shell_NotifyIconW(op, &nid_nt);
5557 }
5558 }
5559
5560 return ret;
5561 }
5562
5563 // Remove the icon in the task tray
MsHideIconOnTray()5564 void MsHideIconOnTray()
5565 {
5566 if (MsIsNt() == false)
5567 {
5568 Shell_NotifyIcon(NIM_DELETE, &nid);
5569 }
5570 else
5571 {
5572 Shell_NotifyIconW(NIM_DELETE, &nid_nt);
5573 }
5574
5575 tray_inited = false;
5576 }
5577
5578 // Insert a menu item
MsInsertMenu(HMENU hMenu,UINT pos,UINT flags,UINT_PTR id_new_item,wchar_t * lp_new_item)5579 bool MsInsertMenu(HMENU hMenu, UINT pos, UINT flags, UINT_PTR id_new_item, wchar_t *lp_new_item)
5580 {
5581 bool ret;
5582
5583 if (MsIsNt())
5584 {
5585 ret = InsertMenuW(hMenu, pos, flags, id_new_item, lp_new_item);
5586 }
5587 else
5588 {
5589 char *s = CopyUniToStr(lp_new_item);
5590 ret = InsertMenuA(hMenu, pos, flags, id_new_item, s);
5591 Free(s);
5592 }
5593
5594 return ret;
5595 }
5596
5597 // Adding a menu item
MsAppendMenu(HMENU hMenu,UINT flags,UINT_PTR id,wchar_t * str)5598 bool MsAppendMenu(HMENU hMenu, UINT flags, UINT_PTR id, wchar_t *str)
5599 {
5600 bool ret;
5601
5602 if (MsIsNt())
5603 {
5604 ret = AppendMenuW(hMenu, flags, id, str);
5605 }
5606 else
5607 {
5608 char *s = CopyUniToStr(str);
5609 ret = AppendMenuA(hMenu, flags, id, s);
5610 Free(s);
5611 }
5612
5613 return ret;
5614 }
5615
5616 // Display the menu
MsUserModeTrayMenu(HWND hWnd)5617 void MsUserModeTrayMenu(HWND hWnd)
5618 {
5619 HMENU h;
5620 POINT p;
5621 wchar_t tmp[MAX_SIZE];
5622 wchar_t caption[MAX_SIZE];
5623 // Validate arguments
5624 if (hWnd == NULL)
5625 {
5626 return;
5627 }
5628
5629 // Create a menu
5630 h = CreatePopupMenu();
5631 MsAppendMenu(h, MF_ENABLED | MF_STRING, 10001, _UU("SVC_USERMODE_MENU_1"));
5632 MsAppendMenu(h, MF_SEPARATOR, 10002, NULL);
5633
5634 if (MsIsNt())
5635 {
5636 GetWindowTextW(hWnd, caption, sizeof(caption));
5637 }
5638 else
5639 {
5640 char tmp[MAX_SIZE];
5641 GetWindowTextA(hWnd, tmp, sizeof(tmp));
5642 StrToUni(caption, sizeof(caption), tmp);
5643 }
5644
5645 UniFormat(tmp, sizeof(tmp), _UU("SVC_USERMODE_MENU_2"), caption);
5646 MsAppendMenu(h, MF_ENABLED | MF_STRING, 10003, tmp);
5647
5648 // Display the menu
5649 GetCursorPos(&p);
5650
5651 SetForegroundWindow(hWnd);
5652 TrackPopupMenu(h, TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL);
5653 PostMessage(hWnd, WM_NULL, 0, 0);
5654
5655 DestroyMenu(h);
5656 }
5657
5658 // Window procedure for the user mode
MsUserModeWindowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)5659 LRESULT CALLBACK MsUserModeWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
5660 {
5661 wchar_t tmp[MAX_SIZE];
5662 char title[MAX_SIZE];
5663 wchar_t title_w[MAX_SIZE];
5664 char value_name[MAX_SIZE];
5665 static UINT taskbar_msg = 0;
5666 // Validate arguments
5667 if (hWnd == NULL)
5668 {
5669 return 0;
5670 }
5671
5672 if (msg == taskbar_msg && taskbar_msg != 0)
5673 {
5674 // The taskbar was regenerated
5675 if (MsRegReadInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, value_name) == 0 &&
5676 service_for_9x_mode == false)
5677 {
5678 MsRestoreIconOnTray();
5679 }
5680 }
5681
5682 switch (msg)
5683 {
5684 case WM_ENDSESSION:
5685 // Resume
5686 if (wParam == false)
5687 {
5688 break;
5689 }
5690 case WM_CREATE:
5691 // Start
5692 exiting = false;
5693 g_start();
5694 GetWindowText(hWnd, title, sizeof(title));
5695 StrToUni(title_w, sizeof(title_w), title);
5696 UniFormat(tmp, sizeof(tmp), _UU("SVC_TRAY_TOOLTIP"), title);
5697
5698 if (taskbar_msg == 0)
5699 {
5700 taskbar_msg = RegisterWindowMessage("TaskbarCreated");
5701 }
5702
5703 Format(value_name, sizeof(value_name), SVC_HIDETRAY_REG_VALUE, title_w);
5704 if (MsRegReadInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, value_name) == 0 &&
5705 service_for_9x_mode == false)
5706 {
5707 MsShowIconOnTray(hWnd, tray_icon, tmp, WM_APP + 33);
5708 }
5709
5710 break;
5711 case WM_APP + 33:
5712 if (wParam == 1)
5713 {
5714 // The operation to the icon in the task tray
5715 switch (lParam)
5716 {
5717 case WM_RBUTTONDOWN:
5718 // Right click
5719 MsUserModeTrayMenu(hWnd);
5720 break;
5721 case WM_LBUTTONDBLCLK:
5722 // Left double-click
5723 break;
5724 }
5725 }
5726 break;
5727 case WM_LBUTTONDOWN:
5728 MsUserModeTrayMenu(hWnd);
5729 break;
5730 case WM_QUERYENDSESSION:
5731 if (exiting == false)
5732 {
5733 exiting = true;
5734 MsHideIconOnTray();
5735 g_stop();
5736 DestroyWindow(hWnd);
5737 }
5738 return TRUE;
5739 case WM_CLOSE:
5740 // Stop
5741 if (exiting == false)
5742 {
5743 exiting = true;
5744 g_stop();
5745 MsHideIconOnTray();
5746 DestroyWindow(hWnd);
5747 }
5748 break;
5749 case WM_DESTROY:
5750 wnd_end = true;
5751 break;
5752 case WM_COMMAND:
5753 switch (wParam)
5754 {
5755 case 10001:
5756 GetWindowText(hWnd, title, sizeof(title));
5757 StrToUni(title_w, sizeof(title_w), title);
5758 // Display a confirmation message
5759 if (MsgBoxEx(hWnd, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 |
5760 MB_SYSTEMMODAL, _UU("SVC_HIDE_TRAY_MSG"), title, title) == IDOK)
5761 {
5762 char tmp[MAX_SIZE];
5763 Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, title_w);
5764 // Write to the registry
5765 MsRegWriteInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp, 1);
5766 // Hide the icon
5767 MsHideIconOnTray();
5768 }
5769 break;
5770 case 10003:
5771 SendMessage(hWnd, WM_CLOSE, 0, 0);
5772 break;
5773 }
5774 break;
5775 }
5776 return DefWindowProc(hWnd, msg, wParam, lParam);
5777 }
5778
5779 // Get the name of PenCore.dll
MsGetPenCoreDllFileName()5780 char *MsGetPenCoreDllFileName()
5781 {
5782 /*if (Is64())
5783 {
5784 if (IsX64())
5785 {
5786 return PENCORE_DLL_NAME_X64;
5787 }
5788 else
5789 {
5790 return PENCORE_DLL_NAME_IA64;
5791 }
5792 }
5793 else*/
5794 {
5795 return PENCORE_DLL_NAME;
5796 }
5797 }
5798
5799 // Get whether this instance is in user mode
MsIsUserMode()5800 bool MsIsUserMode()
5801 {
5802 return is_usermode;
5803 }
5804
5805 // Command to terminate the user-mode from the service side
MsStopUserModeFromService()5806 void MsStopUserModeFromService()
5807 {
5808 if (hWndUsermode != NULL)
5809 {
5810 PostMessage(hWndUsermode, WM_CLOSE, 0, 0);
5811 }
5812 }
5813
5814 // Only run the test (for debugging)
MsTestOnly()5815 void MsTestOnly()
5816 {
5817 g_start();
5818 GetLine(NULL, 0);
5819 g_stop();
5820
5821 _exit(0);
5822 }
5823
5824 // Stop the user-mode service
MsStopUserModeSvc(char * svc_name)5825 void MsStopUserModeSvc(char *svc_name)
5826 {
5827 void *p;
5828 // Validate arguments
5829 if (svc_name == NULL)
5830 {
5831 return;
5832 }
5833
5834 p = MsCreateUserModeSvcGlocalPulse(svc_name);
5835 if (p == NULL)
5836 {
5837 return;
5838 }
5839
5840 MsSendGlobalPulse(p);
5841
5842 MsCloseGlobalPulse(p);
5843 }
5844
5845 // Creating a global pulse for user-mode service
MsCreateUserModeSvcGlocalPulse(char * svc_name)5846 void *MsCreateUserModeSvcGlocalPulse(char *svc_name)
5847 {
5848 char name[MAX_SIZE];
5849 // Validate arguments
5850 if (svc_name == NULL)
5851 {
5852 return NULL;
5853 }
5854
5855 MsGenerateUserModeSvcGlobalPulseName(name, sizeof(name), svc_name);
5856
5857 return MsOpenOrCreateGlobalPulse(name);
5858 }
5859
5860 // Get the global pulse name for the user-mode service
MsGenerateUserModeSvcGlobalPulseName(char * name,UINT size,char * svc_name)5861 void MsGenerateUserModeSvcGlobalPulseName(char *name, UINT size, char *svc_name)
5862 {
5863 wchar_t tmp[MAX_SIZE];
5864 UCHAR hash[SHA1_SIZE];
5865 // Validate arguments
5866 if (name == NULL || svc_name == NULL)
5867 {
5868 return;
5869 }
5870
5871 UniFormat(tmp, sizeof(tmp), L"usersvc_%S_@_%s", svc_name, MsGetUserNameW());
5872
5873 UniTrim(tmp);
5874 UniStrUpper(tmp);
5875
5876 HashSha1(hash, tmp, UniStrLen(tmp) * sizeof(wchar_t));
5877
5878 BinToStr(name, size, hash, sizeof(hash));
5879 }
5880
5881 // Declare the beginning of use of a VLAN card
MsBeginVLanCard()5882 void MsBeginVLanCard()
5883 {
5884 Inc(vlan_card_counter);
5885 }
5886
5887 // Declare the ending of use of a VLAN card
MsEndVLanCard()5888 void MsEndVLanCard()
5889 {
5890 Dec(vlan_card_counter);
5891 }
5892
5893 // Return the flag whether the VLAN cards must be stopped
MsIsVLanCardShouldStop()5894 bool MsIsVLanCardShouldStop()
5895 {
5896 return vlan_card_should_stop_flag;
5897 }
5898
5899 // Suspend procs
MsProcEnterSuspend()5900 void MsProcEnterSuspend()
5901 {
5902 UINT64 giveup_tick = Tick64() + 2000;
5903 UINT num = Count(vlan_card_counter);
5904
5905 vlan_is_in_suspend_mode = true;
5906
5907 vlan_card_should_stop_flag = true;
5908
5909 vlan_suspend_mode_begin_tick = Tick64();
5910
5911 while (true)
5912 {
5913 UINT64 now = Tick64();
5914
5915 if (now >= giveup_tick)
5916 {
5917 break;
5918 }
5919
5920 if (Count(vlan_card_counter) == 0)
5921 {
5922 break;
5923 }
5924
5925 SleepThread(100);
5926 }
5927
5928 if (num >= 1)
5929 {
5930 SleepThread(3000);
5931 }
5932 }
MsProcLeaveSuspend()5933 void MsProcLeaveSuspend()
5934 {
5935 vlan_card_should_stop_flag = false;
5936 vlan_is_in_suspend_mode = false;
5937 vlan_suspend_mode_begin_tick = Tick64();
5938 }
MsGetSuspendModeBeginTick()5939 UINT64 MsGetSuspendModeBeginTick()
5940 {
5941 if (vlan_is_in_suspend_mode)
5942 {
5943 return Tick64();
5944 }
5945
5946 return vlan_suspend_mode_begin_tick;
5947 }
5948
5949 // Suspend handler window proc
MsSuspendHandlerWindowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)5950 LRESULT CALLBACK MsSuspendHandlerWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
5951 {
5952 MS_SUSPEND_HANDLER *h;
5953 CREATESTRUCT *cs;
5954 // Validate arguments
5955 if (hWnd == NULL)
5956 {
5957 return 0;
5958 }
5959
5960 h = (MS_SUSPEND_HANDLER *)GetWindowLongPtrA(hWnd, GWLP_USERDATA);
5961 if (h == NULL && msg != WM_CREATE)
5962 {
5963 goto LABEL_END;
5964 }
5965
5966 switch (msg)
5967 {
5968 case WM_CREATE:
5969 cs = (CREATESTRUCT *)lParam;
5970 h = (MS_SUSPEND_HANDLER *)cs->lpCreateParams;
5971 SetWindowLongPtrA(hWnd, GWLP_USERDATA, (LONG_PTR)h);
5972 break;
5973
5974 case WM_POWERBROADCAST:
5975 if (MsIsVista())
5976 {
5977 switch (wParam)
5978 {
5979 case PBT_APMSUSPEND:
5980 MsProcEnterSuspend();
5981 return 1;
5982
5983 case PBT_APMRESUMEAUTOMATIC:
5984 case PBT_APMRESUMESUSPEND:
5985 MsProcLeaveSuspend();
5986 return 1;
5987 }
5988 }
5989 break;
5990
5991 case WM_CLOSE:
5992 /*if (h->AboutToClose == false)
5993 {
5994 return 0;
5995 }*/
5996 break;
5997
5998 case WM_DESTROY:
5999 PostQuitMessage(0);
6000 break;
6001 }
6002
6003 LABEL_END:
6004 return DefWindowProc(hWnd, msg, wParam, lParam);
6005 }
6006
6007 // Suspend handler thread
MsSuspendHandlerThreadProc(THREAD * thread,void * param)6008 void MsSuspendHandlerThreadProc(THREAD *thread, void *param)
6009 {
6010 char wndclass_name[MAX_PATH];
6011 WNDCLASS wc;
6012 HWND hWnd;
6013 MSG msg;
6014 MS_SUSPEND_HANDLER *h = (MS_SUSPEND_HANDLER *)param;
6015 // Validate arguments
6016 if (h == NULL || thread == NULL)
6017 {
6018 return;
6019 }
6020
6021 Format(wndclass_name, sizeof(wndclass_name), "WNDCLASS_%X", Rand32());
6022
6023 Zero(&wc, sizeof(wc));
6024 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
6025 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
6026 wc.hIcon = NULL;
6027 wc.hInstance = ms->hInst;
6028 wc.lpfnWndProc = MsSuspendHandlerWindowProc;
6029 wc.lpszClassName = wndclass_name;
6030 if (RegisterClassA(&wc) == 0)
6031 {
6032 NoticeThreadInit(thread);
6033 return;
6034 }
6035
6036 hWnd = CreateWindowA(wndclass_name, wndclass_name, WS_OVERLAPPEDWINDOW,
6037 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
6038 NULL, NULL, ms->hInst, h);
6039
6040 h->hWnd = hWnd;
6041
6042 NoticeThreadInit(thread);
6043
6044 if (hWnd == NULL)
6045 {
6046 UnregisterClassA(wndclass_name, ms->hInst);
6047 return;
6048 }
6049
6050 //ShowWindow(hWnd, SW_SHOWNORMAL);
6051
6052 while (GetMessage(&msg, NULL, 0, 0))
6053 {
6054 TranslateMessage(&msg);
6055 DispatchMessage(&msg);
6056 }
6057
6058 vlan_card_should_stop_flag = false;
6059 vlan_is_in_suspend_mode = false;
6060 vlan_suspend_mode_begin_tick = 0;
6061
6062 DestroyWindow(hWnd);
6063
6064 UnregisterClassA(wndclass_name, ms->hInst);
6065 }
6066
6067 // New suspend handler
MsNewSuspendHandler()6068 MS_SUSPEND_HANDLER *MsNewSuspendHandler()
6069 {
6070 THREAD *t;
6071 MS_SUSPEND_HANDLER *h;
6072
6073 if (Inc(suspend_handler_singleton) >= 2)
6074 {
6075 Dec(suspend_handler_singleton);
6076 return NULL;
6077 }
6078
6079 vlan_card_should_stop_flag = false;
6080 vlan_is_in_suspend_mode = false;
6081 vlan_suspend_mode_begin_tick = 0;
6082
6083 h = ZeroMalloc(sizeof(MS_SUSPEND_HANDLER));
6084
6085 t = NewThread(MsSuspendHandlerThreadProc, h);
6086
6087 WaitThreadInit(t);
6088
6089 h->Thread = t;
6090
6091 return h;
6092 }
6093
MsFreeSuspendHandler(MS_SUSPEND_HANDLER * h)6094 void MsFreeSuspendHandler(MS_SUSPEND_HANDLER *h)
6095 {
6096 // Validate arguments
6097 if (h == NULL)
6098 {
6099 return;
6100 }
6101
6102 if (h->hWnd != NULL)
6103 {
6104 h->AboutToClose = true;
6105 PostMessageA(h->hWnd, WM_CLOSE, 0, 0);
6106 }
6107
6108 WaitThread(h->Thread, INFINITE);
6109 ReleaseThread(h->Thread);
6110
6111 Free(h);
6112
6113 Dec(suspend_handler_singleton);
6114
6115 vlan_card_should_stop_flag = false;
6116 }
6117
6118 // Start in user mode
MsUserMode(char * title,SERVICE_FUNCTION * start,SERVICE_FUNCTION * stop,UINT icon)6119 void MsUserMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon)
6120 {
6121 wchar_t *title_w = CopyStrToUni(title);
6122
6123 MsUserModeW(title_w, start, stop, icon);
6124
6125 Free(title_w);
6126 }
MsUserModeW(wchar_t * title,SERVICE_FUNCTION * start,SERVICE_FUNCTION * stop,UINT icon)6127 void MsUserModeW(wchar_t *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon)
6128 {
6129 WNDCLASS wc;
6130 HINSTANCE hDll;
6131 HWND hWnd;
6132 MSG msg;
6133 INSTANCE *inst;
6134 char title_a[MAX_PATH];
6135 MS_USERMODE_SVC_PULSE_THREAD_PARAM p;
6136 THREAD *recv_thread = NULL;
6137 // Validate arguments
6138 if (title == NULL || start == NULL || stop == NULL)
6139 {
6140 return;
6141 }
6142
6143 UniToStr(title_a, sizeof(title_a), title);
6144
6145 is_usermode = true;
6146 g_start = start;
6147 g_stop = stop;
6148
6149 inst = NewSingleInstance(NULL);
6150 if (inst == NULL)
6151 {
6152 if (service_for_9x_mode == false)
6153 {
6154 // Do not display an error if Win9x service mode
6155 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_USERMODE_MUTEX"), ms->ExeFileNameW);
6156 }
6157 return;
6158 }
6159
6160 if (Is64())
6161 {
6162 hDll = MsLoadLibraryAsDataFile(MsGetPenCoreDllFileName());
6163 }
6164 else
6165 {
6166 hDll = MsLoadLibrary(MsGetPenCoreDllFileName());
6167 }
6168
6169 // Read icon
6170 tray_icon = LoadImage(hDll, MAKEINTRESOURCE(icon), IMAGE_ICON, 16, 16,
6171 (MsIsNt() ? LR_SHARED : 0) | LR_VGACOLOR);
6172
6173 // Creating the main window
6174 Zero(&wc, sizeof(wc));
6175 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
6176 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
6177 wc.hIcon = LoadIcon(hDll, MAKEINTRESOURCE(icon));
6178 wc.hInstance = ms->hInst;
6179 wc.lpfnWndProc = MsUserModeWindowProc;
6180 wc.lpszClassName = title_a;
6181 if (RegisterClass(&wc) == 0)
6182 {
6183 return;
6184 }
6185
6186 hWnd = CreateWindow(title_a, title_a, WS_OVERLAPPEDWINDOW,
6187 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
6188 NULL, NULL, ms->hInst, NULL);
6189
6190 if (hWnd == NULL)
6191 {
6192 return;
6193 }
6194
6195 Zero(&p, sizeof(p));
6196 p.hWnd = hWnd;
6197 p.GlobalPulse = MsCreateUserModeSvcGlocalPulse(g_service_name);
6198
6199 if (p.GlobalPulse != NULL)
6200 {
6201 // Start the global pulse monitoring thread for termination
6202 p.Halt = false;
6203
6204 recv_thread = NewThread(MsUserModeGlobalPulseRecvThread, &p);
6205 }
6206
6207 hWndUsermode = hWnd;
6208
6209 wnd_end = false;
6210 // Window loop
6211 while (wnd_end == false)
6212 {
6213 GetMessage(&msg, NULL, 0, 0);
6214 TranslateMessage(&msg);
6215 DispatchMessage(&msg);
6216 }
6217
6218 FreeSingleInstance(inst);
6219
6220 p.hWnd = NULL;
6221
6222 hWndUsermode = NULL;
6223
6224 if (p.GlobalPulse != NULL)
6225 {
6226 // Terminate the monitoring thread of termination global pulse
6227 p.Halt = true;
6228 MsSendGlobalPulse(p.GlobalPulse);
6229
6230 WaitThread(recv_thread, INFINITE);
6231 ReleaseThread(recv_thread);
6232
6233 MsCloseGlobalPulse(p.GlobalPulse);
6234 }
6235
6236 // Might abort
6237 _exit(0);
6238 }
6239
6240 // The thread that wait for global pulse to stop the user mode service
MsUserModeGlobalPulseRecvThread(THREAD * thread,void * param)6241 void MsUserModeGlobalPulseRecvThread(THREAD *thread, void *param)
6242 {
6243 MS_USERMODE_SVC_PULSE_THREAD_PARAM *p = (MS_USERMODE_SVC_PULSE_THREAD_PARAM *)param;
6244 // Validate arguments
6245 if (thread == NULL || p == NULL)
6246 {
6247 return;
6248 }
6249
6250 while (p->Halt == false)
6251 {
6252 if (MsWaitForGlobalPulse(p->GlobalPulse, INFINITE))
6253 {
6254 break;
6255 }
6256 }
6257
6258 if (p->hWnd != NULL)
6259 {
6260 PostMessageA(p->hWnd, WM_CLOSE, 0, 0);
6261 }
6262 }
6263
6264 // Service stopping procedure main thread
MsServiceStoperMainThread(THREAD * t,void * p)6265 void MsServiceStoperMainThread(THREAD *t, void *p)
6266 {
6267 // Stopping procedure
6268 g_stop();
6269 }
6270
6271 // Service stop procedure
MsServiceStopProc()6272 bool MsServiceStopProc()
6273 {
6274 THREAD *thread;
6275 bool ret = true;
6276 UINT64 selfkill_timeout = Tick64() + SVC_SELFKILL_TIMEOUT;
6277
6278 thread = NewThread(MsServiceStoperMainThread, NULL);
6279
6280 while (WaitThread(thread, 250) == false)
6281 {
6282 if (Tick64() >= selfkill_timeout)
6283 {
6284 // Suicide when it freezes
6285 ret = false;
6286 break;
6287 }
6288 // During stopping procedure to complete, call the SetServiceStatus periodically
6289 status.dwWin32ExitCode = 0;
6290 status.dwWaitHint = 100000;
6291 status.dwCheckPoint++;
6292 status.dwCurrentState = SERVICE_STOP_PENDING;
6293 _SetServiceStatus(ssh, &status);
6294 }
6295
6296 // Report that the stopping is complete
6297 status.dwWin32ExitCode = 0;
6298 status.dwWaitHint = 0;
6299 status.dwCheckPoint = 0;
6300 status.dwCurrentState = SERVICE_STOPPED;
6301 _SetServiceStatus(ssh, &status);
6302
6303 if (ret == false)
6304 {
6305 // Force termination here if this has committed suicide
6306 _exit(-1);
6307 }
6308 else
6309 {
6310 ReleaseThread(thread);
6311 }
6312
6313 return ret;
6314 }
6315
6316 // Service handler
MsServiceHandler(DWORD opcode)6317 void CALLBACK MsServiceHandler(DWORD opcode)
6318 {
6319 switch (opcode)
6320 {
6321 case SERVICE_CONTROL_SHUTDOWN:
6322 case SERVICE_CONTROL_STOP:
6323 // Stopping request
6324 status.dwWin32ExitCode = 0;
6325 status.dwWaitHint = 100000;
6326 status.dwCheckPoint = 0;
6327 status.dwCurrentState = SERVICE_STOP_PENDING;
6328
6329 // Set the stopping event
6330 if (service_stop_event != NULL)
6331 {
6332 SetEvent(service_stop_event);
6333 }
6334 break;
6335 }
6336
6337 _SetServiceStatus(ssh, &status);
6338 }
6339
6340 // Dispatch function of the service
MsServiceDispatcher(DWORD argc,LPTSTR * argv)6341 void CALLBACK MsServiceDispatcher(DWORD argc, LPTSTR *argv)
6342 {
6343 // Creating a stopping event
6344 service_stop_event = CreateEventA(NULL, true, false, NULL);
6345
6346 // Preparing for the service
6347 Zero(&status, sizeof(status));
6348 status.dwServiceType = SERVICE_WIN32;
6349 status.dwCurrentState = SERVICE_START_PENDING;
6350 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
6351
6352 ssh = _RegisterServiceCtrlHandler(g_service_name, MsServiceHandler);
6353
6354 if (ssh == NULL)
6355 {
6356 MessageBox(NULL, "RegisterServiceCtrlHandler() Failed.", "MsServiceDispatcher()", MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);
6357 return;
6358 }
6359
6360 status.dwWaitHint = 300000;
6361 status.dwCheckPoint = 0;
6362 status.dwCheckPoint++;
6363 status.dwCurrentState = SERVICE_START_PENDING;
6364 _SetServiceStatus(ssh, &status);
6365
6366 // Report the start completion
6367 status.dwWaitHint = 0;
6368 status.dwCheckPoint = 0;
6369 status.dwCurrentState = SERVICE_RUNNING;
6370 _SetServiceStatus(ssh, &status);
6371
6372 //// Initialization
6373 // Start of the Mayaqua
6374 InitMayaqua(false, false, 0, NULL);
6375
6376 // Stop the MS-IME
6377 MsDisableIme();
6378
6379 // Service operation start
6380 g_start();
6381 MsUpdateServiceConfig(g_service_name);
6382
6383 // Wait for the stopping event to be signaled state
6384 WaitForSingleObject(service_stop_event, INFINITE);
6385
6386 // Service operation stop
6387 MsServiceStopProc();
6388 }
6389
6390 // Start as a test mode
MsTestMode(char * title,SERVICE_FUNCTION * start,SERVICE_FUNCTION * stop)6391 void MsTestMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)
6392 {
6393 wchar_t *title_w = CopyStrToUni(title);
6394
6395 MsTestModeW(title_w, start, stop);
6396 Free(title_w);
6397 }
MsTestModeW(wchar_t * title,SERVICE_FUNCTION * start,SERVICE_FUNCTION * stop)6398 void MsTestModeW(wchar_t *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)
6399 {
6400 INSTANCE *inst;
6401 // Validate arguments
6402 if (title == NULL || start == NULL || stop == NULL)
6403 {
6404 return;
6405 }
6406
6407 is_usermode = true;
6408
6409 inst = NewSingleInstance(NULL);
6410 if (inst == NULL)
6411 {
6412 // Already started
6413 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_TEST_MUTEX"), ms->ExeFileNameW);
6414 return;
6415 }
6416
6417 // Start
6418 start();
6419
6420 // Display the message
6421 MsgBoxEx(NULL, MB_ICONINFORMATION | MB_SYSTEMMODAL, _UU("SVC_TEST_MSG"), title);
6422
6423 // Stop
6424 stop();
6425
6426 FreeSingleInstance(inst);
6427 }
6428
6429 // Write the process ID of the process which is calling the service manager
MsWriteCallingServiceManagerProcessId(char * svcname,UINT pid)6430 void MsWriteCallingServiceManagerProcessId(char *svcname, UINT pid)
6431 {
6432 char tmp[MAX_PATH];
6433
6434 Format(tmp, sizeof(tmp), SVC_CALLING_SM_PROCESS_ID_KEY, svcname);
6435
6436 if (pid != 0)
6437 {
6438 MsRegWriteInt(REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE, pid);
6439 MsRegWriteInt(REG_CURRENT_USER, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE, pid);
6440 }
6441 else
6442 {
6443 MsRegDeleteValue(REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);
6444 MsRegDeleteKey(REG_LOCAL_MACHINE, tmp);
6445
6446 MsRegDeleteValue(REG_CURRENT_USER, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);
6447 MsRegDeleteKey(REG_CURRENT_USER, tmp);
6448 }
6449 }
6450
6451 // Get the process ID of the process which is calling the service manager
MsReadCallingServiceManagerProcessId(char * svcname,bool current_user)6452 UINT MsReadCallingServiceManagerProcessId(char *svcname, bool current_user)
6453 {
6454 char tmp[MAX_PATH];
6455 // Validate arguments
6456 if (svcname == NULL)
6457 {
6458 return 0;
6459 }
6460
6461 Format(tmp, sizeof(tmp), SVC_CALLING_SM_PROCESS_ID_KEY, svcname);
6462
6463 return MsRegReadInt(current_user ? REG_CURRENT_USER : REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);
6464 }
6465
6466 // Dispatch function of the service
MsScmDispatcher(DWORD argc,LPTSTR * argv)6467 void CALLBACK MsScmDispatcher(DWORD argc, LPTSTR *argv)
6468 {
6469 }
6470
6471 // Service main function
MsService(char * name,SERVICE_FUNCTION * start,SERVICE_FUNCTION * stop,UINT icon,char * cmd_line)6472 UINT MsService(char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon, char *cmd_line)
6473 {
6474 UINT mode;
6475 UINT ret = 0;
6476 char *arg;
6477 wchar_t *arg_w;
6478 TOKEN_LIST *t = NULL;
6479 UNI_TOKEN_LIST *ut = NULL;
6480 char *service_name;
6481 wchar_t *service_title;
6482 wchar_t *service_description;
6483 wchar_t *service_title_uni;
6484 char tmp[MAX_SIZE];
6485 bool restoreReg = false;
6486 bool silent = false;
6487 bool is_win32_service_mode = false;
6488 // Validate arguments
6489 if (name == NULL || start == NULL || stop == NULL)
6490 {
6491 return ret;
6492 }
6493
6494 g_start = start;
6495 g_stop = stop;
6496 StrCpy(g_service_name, sizeof(g_service_name), name);
6497 StrLower(g_service_name);
6498
6499 // Determine whether it's in Win32 service mode
6500 if (cmd_line != NULL && lstrcmpiA(cmd_line, SVC_ARG_SERVICE) == 0)
6501 {
6502 HINSTANCE h_advapi32 = LoadLibraryA("advapi32.dll");
6503
6504 if (h_advapi32 != NULL)
6505 {
6506 // Check whether there is the SCM in the service mode
6507 _StartServiceCtrlDispatcher =
6508 (BOOL (__stdcall *)(const LPSERVICE_TABLE_ENTRY))
6509 GetProcAddress(h_advapi32, "StartServiceCtrlDispatcherW");
6510
6511 _RegisterServiceCtrlHandler =
6512 (SERVICE_STATUS_HANDLE (__stdcall *)(LPCTSTR,LPHANDLER_FUNCTION))
6513 GetProcAddress(h_advapi32, "RegisterServiceCtrlHandlerW");
6514
6515 _SetServiceStatus =
6516 (BOOL (__stdcall *)(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS))
6517 GetProcAddress(h_advapi32, "SetServiceStatus");
6518
6519 if (_StartServiceCtrlDispatcher != NULL &&
6520 _RegisterServiceCtrlHandler != NULL &&
6521 _SetServiceStatus != NULL)
6522 {
6523 is_win32_service_mode = true;
6524 }
6525 }
6526 }
6527
6528 // Run the service using the SCM in the case of Win32 service mode
6529 if (is_win32_service_mode)
6530 {
6531 SERVICE_TABLE_ENTRY dispatch_table[] =
6532 {
6533 {"", MsServiceDispatcher},
6534 {NULL, NULL},
6535 };
6536
6537 MsSetErrorModeToSilent();
6538
6539 if (_StartServiceCtrlDispatcher(dispatch_table) == false)
6540 {
6541 MessageBox(NULL, "StartServiceCtrlDispatcher() Failed.", "MsServiceMode()", MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);
6542 }
6543 else
6544 {
6545 MsUpdateServiceConfig(g_service_name);
6546 }
6547
6548 // Abort here in the case of using the SCM
6549 _exit(0);
6550 return 0;
6551 }
6552
6553 // Start of the Mayaqua
6554 InitMayaqua(false, false, 0, NULL);
6555
6556 // Stop the MS-IME
6557 MsDisableIme();
6558
6559 // Get the information about the service from the string table
6560 Format(tmp, sizeof(tmp), SVC_NAME, name);
6561 service_name = _SS(tmp);
6562 Format(tmp, sizeof(tmp), SVC_TITLE, name);
6563 service_title = _UU(tmp);
6564 service_title_uni = _UU(tmp);
6565 Format(tmp, sizeof(tmp), SVC_DESCRIPT, name);
6566 service_description = _UU(tmp);
6567
6568 if (StrLen(service_name) == 0 || UniStrLen(service_title) == 0)
6569 {
6570 // The service information isn't found
6571 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_NOT_FOUND"), name);
6572 }
6573 else
6574 {
6575 wchar_t path[MAX_SIZE];
6576 // Check the argument
6577 mode = SVC_MODE_NONE;
6578
6579 t = GetCommandLineToken();
6580 arg = NULL;
6581
6582 ut = GetCommandLineUniToken();
6583 arg_w = NULL;
6584
6585 if (t->NumTokens >= 1)
6586 {
6587 arg = t->Token[0];
6588 }
6589 if(t->NumTokens >= 2)
6590 {
6591 if(StrCmpi(t->Token[1], SVC_ARG_SILENT) == 0)
6592 {
6593 silent = true;
6594 }
6595 }
6596
6597 if (ut->NumTokens >= 1)
6598 {
6599 arg_w = ut->Token[0];
6600 }
6601
6602 if (arg != NULL)
6603 {
6604 if (StrCmpi(arg, SVC_ARG_INSTALL) == 0)
6605 {
6606 mode = SVC_MODE_INSTALL;
6607 }
6608 if (StrCmpi(arg, SVC_ARG_UNINSTALL) == 0)
6609 {
6610 mode = SVC_MODE_UNINSTALL;
6611 }
6612 if (StrCmpi(arg, SVC_ARG_START) == 0)
6613 {
6614 mode = SVC_MODE_START;
6615 }
6616 if (StrCmpi(arg, SVC_ARG_STOP) == 0)
6617 {
6618 mode = SVC_MODE_STOP;
6619 }
6620 if (StrCmpi(arg, SVC_ARG_TEST) == 0)
6621 {
6622 mode = SVC_MODE_TEST;
6623 }
6624 if (StrCmpi(arg, SVC_ARG_USERMODE) == 0)
6625 {
6626 mode = SVC_MODE_USERMODE;
6627 }
6628 if (StrCmpi(arg, SVC_ARG_SETUP_INSTALL) == 0)
6629 {
6630 mode = SVC_MODE_SETUP_INSTALL;
6631 }
6632 if (StrCmpi(arg, SVC_ARG_SETUP_UNINSTALL) == 0)
6633 {
6634 mode = SVC_MODE_SETUP_UNINSTALL;
6635 }
6636 if (StrCmpi(arg, SVC_ARG_WIN9X_SERVICE) == 0)
6637 {
6638 mode = SVC_MODE_WIN9X_SERVICE;
6639 }
6640 if (StrCmpi(arg, SVC_ARG_WIN9X_INSTALL) == 0)
6641 {
6642 mode = SVC_MODE_WIN9X_INSTALL;
6643 }
6644 if (StrCmpi(arg, SVC_ARG_WIN9X_UNINSTALL) == 0)
6645 {
6646 mode = SVC_MODE_WIN9X_UNINSTALL;
6647 }
6648 if (StrCmpi(arg, SVC_ARG_TCP) == 0)
6649 {
6650 mode = SVC_MODE_TCP;
6651 }
6652 if (StrCmpi(arg, SVC_ARG_TCP_UAC) == 0)
6653 {
6654 mode = SVC_MODE_TCP_UAC;
6655 }
6656 if (StrCmpi(arg, SVC_ARG_TCP_SETUP) == 0)
6657 {
6658 mode = SVC_MODE_TCPSETUP;
6659 }
6660 if (StrCmpi(arg, SVC_ARG_TRAFFIC) == 0)
6661 {
6662 mode = SVC_MODE_TRAFFIC;
6663 }
6664 if (StrCmpi(arg, SVC_ARG_UIHELP) == 0)
6665 {
6666 mode = SVC_MODE_UIHELP;
6667 }
6668 if (StrCmpi(arg, SVC_ARG_USERMODE_SHOWTRAY) == 0)
6669 {
6670 char tmp[MAX_SIZE];
6671 mode = SVC_MODE_USERMODE;
6672 Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, service_title);
6673 MsRegDeleteValue(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp);
6674 }
6675 if (StrCmpi(arg, SVC_ARG_USERMODE_HIDETRAY) == 0)
6676 {
6677 char tmp[MAX_SIZE];
6678 mode = SVC_MODE_USERMODE;
6679 Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, service_title);
6680 MsRegWriteInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp, 1);
6681 }
6682 if (StrCmpi(arg, SVC_ARG_SERVICE) == 0)
6683 {
6684 mode = SVC_MODE_SERVICE;
6685 }
6686
6687 if (mode != SVC_MODE_NONE)
6688 {
6689 // Network Config
6690 MsInitGlobalNetworkConfig();
6691 }
6692 }
6693
6694 // Get the command-line name when running as a service
6695 UniFormat(path, sizeof(path), SVC_RUN_COMMANDLINE, ms->ExeFileNameW);
6696
6697 if ((mode == SVC_MODE_INSTALL || mode == SVC_MODE_UNINSTALL || mode == SVC_MODE_START ||
6698 mode == SVC_MODE_STOP || mode == SVC_MODE_SERVICE) &&
6699 (ms->IsNt == false))
6700 {
6701 // Tried to use the command for the NT in non-WindowsNT system
6702 MsgBox(NULL, MB_ICONSTOP, _UU("SVC_NT_ONLY"));
6703 }
6704 else if ((mode == SVC_MODE_INSTALL || mode == SVC_MODE_UNINSTALL || mode == SVC_MODE_START ||
6705 mode == SVC_MODE_STOP || mode == SVC_MODE_SERVICE) &&
6706 (ms->IsAdmin == false))
6707 {
6708 // Do not have Administrators privillage
6709 MsgBox(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_ADMIN"));
6710 }
6711 else
6712 {
6713 // Performs processing depend on mode
6714 switch (mode)
6715 {
6716 case SVC_MODE_NONE:
6717 // Exit by showing a guidance message
6718 if (arg_w != NULL && UniEndWith(arg_w, L".vpn"))
6719 {
6720 if (MsgBox(NULL, MB_ICONQUESTION | MB_YESNO, _UU("CM_VPN_FILE_CLICKED")) == IDYES)
6721 {
6722 wchar_t vpncmgr[MAX_PATH];
6723 wchar_t filename[MAX_PATH];
6724
6725 UniFormat(filename, sizeof(filename), L"\"%s\"", arg_w);
6726
6727 if (Is64() == false)
6728 {
6729 UniFormat(vpncmgr, sizeof(vpncmgr), L"%s\\vpncmgr.exe", MsGetExeDirNameW());
6730 }
6731 else
6732 {
6733 UniFormat(vpncmgr, sizeof(vpncmgr), L"%s\\vpncmgr_x64.exe", MsGetExeDirNameW());
6734 }
6735
6736 RunW(vpncmgr, filename, false, false);
6737 }
6738 }
6739 else
6740 {
6741 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_HELP"),
6742 service_title, service_name, service_title, service_title, service_name, service_title, service_name, service_title, service_name, service_title, service_name, service_title, service_title);
6743 }
6744 break;
6745
6746 case SVC_MODE_SETUP_INSTALL:
6747 // Setup.exe installation mode
6748 // Uninstall the old version
6749 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
6750 restoreReg = true;
6751
6752 if (MsIsServiceInstalled(service_name))
6753 {
6754 if (MsIsServiceRunning(service_name))
6755 {
6756 MsStopService(service_name);
6757 }
6758 MsUninstallService(service_name);
6759 }
6760 if (MsInstallServiceW(service_name, service_title, service_description, path) == false)
6761 {
6762 ret = 1;
6763 }
6764 MsStartService(service_name);
6765 MsWriteCallingServiceManagerProcessId(service_name, 0);
6766 break;
6767
6768 case SVC_MODE_SETUP_UNINSTALL:
6769 // Setup.exe uninstall mode
6770 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
6771 restoreReg = true;
6772
6773 if (MsIsServiceInstalled(service_name))
6774 {
6775 if (MsIsServiceRunning(service_name))
6776 {
6777 MsStopService(service_name);
6778 }
6779 if (MsUninstallService(service_name) == false)
6780 {
6781 ret = 1;
6782 }
6783 }
6784 break;
6785
6786 case SVC_MODE_INSTALL:
6787 // Install the service
6788 // Check whether it is already installed
6789 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
6790 restoreReg = true;
6791
6792 if (MsIsServiceInstalled(service_name))
6793 {
6794 // Already installed
6795 // Show a message asking if you want to uninstall
6796 if(silent == true)
6797 {
6798 // Always cancel the operation
6799 break;
6800 }
6801 if (MsgBoxEx(NULL, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("SVC_ALREADY_INSTALLED"),
6802 service_title, service_name) == IDNO)
6803 {
6804 // Cancel the operation
6805 break;
6806 }
6807 else
6808 {
6809 // Whether the existing service is working?
6810 if (MsIsServiceRunning(service_name))
6811 {
6812 // Try to stop
6813 if (MsStopService(service_name) == false)
6814 {
6815 // Failed to stop
6816 if(silent == false)
6817 {
6818 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_STOP_FAILED"),
6819 service_title, service_name);
6820 }
6821 break;
6822 }
6823 }
6824 // Uninstall
6825 if (MsUninstallService(service_name) == false)
6826 {
6827 // Failed to uninstall
6828 if(silent == false)
6829 {
6830 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_UNINSTALL_FAILED"),
6831 service_title, service_name);
6832 }
6833 break;
6834 }
6835 }
6836 }
6837
6838 // Do the installation
6839 if (MsInstallServiceW(service_name, service_title, service_description, path) == false)
6840 {
6841 // Failed to install
6842 if(silent == false)
6843 {
6844 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_INSTALL_FAILED"),
6845 service_title, service_name);
6846 }
6847 break;
6848 }
6849
6850 // Start the service
6851 if (MsStartService(service_name) == false)
6852 {
6853 // Failed to start
6854 if(silent == false)
6855 {
6856 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_INSTALL_FAILED_2"),
6857 service_title, service_name, path);
6858 }
6859 break;
6860 }
6861
6862 // All successful
6863 if(silent == false)
6864 {
6865 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_INSTALL_OK"),
6866 service_title, service_name, path);
6867 }
6868 break;
6869
6870 case SVC_MODE_UNINSTALL:
6871 // Uninstall the service
6872 // Check whether it is already installed
6873 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
6874 restoreReg = true;
6875
6876 if (MsIsServiceInstalled(service_name) == false)
6877 {
6878 if(silent == false)
6879 {
6880 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),
6881 service_title, service_name, path);
6882 }
6883 break;
6884 }
6885
6886 // If the service is currently running, stop it
6887 if (MsIsServiceRunning(service_name))
6888 {
6889 // Stop the service
6890 if (MsStopService(service_name) == false)
6891 {
6892 // Failed to stop
6893 if(silent == false)
6894 {
6895 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_STOP_FAILED"),
6896 service_title, service_name);
6897 }
6898 break;
6899 }
6900 }
6901
6902 // Uninstall the service
6903 if (MsUninstallService(service_name) == false)
6904 {
6905 if(silent == false)
6906 {
6907 MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_UNINSTALL_FAILED"),
6908 service_title, service_name);
6909 }
6910 break;
6911 }
6912
6913 // All successful
6914 if(silent == false)
6915 {
6916 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_UNINSTALL_OK"),
6917 service_title, service_name);
6918 }
6919 break;
6920
6921 case SVC_MODE_START:
6922 // Start the service
6923 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
6924 restoreReg = true;
6925
6926 if (MsIsServiceInstalled(service_name) == false)
6927 {
6928 // Service is not installed
6929 if(silent == false)
6930 {
6931 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),
6932 service_title, service_name);
6933 }
6934 break;
6935 }
6936
6937 // Confirm whether the service is running
6938 if (MsIsServiceRunning(service_name))
6939 {
6940 // Service is running
6941 if(silent == false)
6942 {
6943 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVR_ALREADY_START"),
6944 service_title, service_name);
6945 }
6946 break;
6947 }
6948
6949 // Start the service
6950 if (MsStartService(service_name) == false)
6951 {
6952 // Failed to start
6953 if(silent == false)
6954 {
6955 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_START_FAILED"),
6956 service_title, service_name);
6957 }
6958 break;
6959 }
6960
6961 // All successful
6962 if(silent == false)
6963 {
6964 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_START_OK"),
6965 service_title, service_name);
6966 }
6967 break;
6968
6969 case SVC_MODE_STOP:
6970 // Stop the service
6971 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
6972 restoreReg = true;
6973
6974 if (MsIsServiceInstalled(service_name) == false)
6975 {
6976 // Service is not installed
6977 if(silent == false)
6978 {
6979 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),
6980 service_title, service_name);
6981 }
6982 break;
6983 }
6984
6985 // Confirm whether the service is running
6986 if (MsIsServiceRunning(service_name) == false)
6987 {
6988 // The service is stopped
6989 if(silent == false)
6990 {
6991 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_ALREADY_STOP"),
6992 service_title, service_name);
6993 }
6994 break;
6995 }
6996 // Stop the service
6997 if (MsStopService(service_name) == false)
6998 {
6999 // Failed to stop
7000 if(silent == false)
7001 {
7002 MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_STOP_FAILED"),
7003 service_title, service_name);
7004 }
7005 break;
7006 }
7007
7008 // All successful
7009 if(silent == false)
7010 {
7011 MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_STOP_OK"),
7012 service_title, service_name);
7013 }
7014 break;
7015
7016 case SVC_MODE_TEST:
7017 // Test mode
7018 MsTestModeW(service_title, start, stop);
7019 break;
7020
7021 case SVC_MODE_WIN9X_SERVICE:
7022 // Win9x service mode (hide icon in the task tray unconditionally)
7023 if (MsIsNt())
7024 {
7025 // Don't do this on Windows 2000 or later
7026 break;
7027 }
7028 service_for_9x_mode = true;
7029 // Not a oblivion to break
7030 case SVC_MODE_USERMODE:
7031 // User mode
7032 MsUserModeW(service_title, start, stop, icon);
7033 break;
7034
7035 case SVC_MODE_WIN9X_INSTALL:
7036 // Win9x installation mode
7037 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
7038 restoreReg = true;
7039
7040 if (MsIsNt() == false)
7041 {
7042 // Adding a registry key
7043 char cmdline[MAX_PATH];
7044 Format(cmdline, sizeof(cmdline), "\"%s\" %s",
7045 MsGetExeFileName(), SVC_ARG_WIN9X_SERVICE);
7046 MsRegWriteStr(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_1,
7047 name, cmdline);
7048 MsRegWriteStr(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_2,
7049 name, cmdline);
7050
7051 // Start
7052 //Run(MsGetExeFileName(), SVC_ARG_WIN9X_SERVICE, false, false);
7053 }
7054 break;
7055
7056 case SVC_MODE_WIN9X_UNINSTALL:
7057 // Win9x uninstall mode
7058 MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
7059 restoreReg = true;
7060
7061 if (MsIsNt() == false)
7062 {
7063 // Delete the registry key
7064 MsRegDeleteValue(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_1,
7065 name);
7066 MsRegDeleteValue(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_2,
7067 name);
7068
7069 // Terminate all the processes of PacketiX VPN Client other than itself
7070 MsKillOtherInstance();
7071 }
7072 break;
7073
7074 case SVC_MODE_SERVICE:
7075 // Run as a service
7076 // Obsolated (2012.12.31) (Do this in the above code)
7077 //MsServiceMode(start, stop);
7078 break;
7079
7080 case SVC_MODE_TCP:
7081 case SVC_MODE_TCP_UAC:
7082 // TCP Utility
7083 InitCedar();
7084 InitWinUi(service_title_uni, NULL, 0);
7085
7086 if (MsIsVista() && MsIsAdmin() == false && mode != SVC_MODE_TCP_UAC)
7087 {
7088 void *handle = NULL;
7089 if (MsExecuteEx2W(ms->ExeFileNameW, SVC_ARG_TCP_UAC_W, &handle, true) == false)
7090 {
7091 ShowTcpIpConfigUtil(NULL, true);
7092 }
7093 else
7094 {
7095 MsWaitProcessExit(handle);
7096 }
7097 }
7098 else
7099 {
7100 ShowTcpIpConfigUtil(NULL, true);
7101 }
7102
7103 FreeWinUi();
7104 FreeCedar();
7105 break;
7106
7107 case SVC_MODE_TCPSETUP:
7108 // TCP optimization mode (This is called by the installer)
7109 InitCedar();
7110 InitWinUi(service_title_uni, NULL, 0);
7111
7112 if (MsIsVista() && MsIsAdmin() == false)
7113 {
7114 void *handle = NULL;
7115 if (MsExecuteEx2W(ms->ExeFileNameW, arg_w, &handle, true) == false)
7116 {
7117 ShowTcpIpConfigUtil(NULL, false);
7118 }
7119 else
7120 {
7121 MsWaitProcessExit(handle);
7122 }
7123 }
7124 else
7125 {
7126 ShowTcpIpConfigUtil(NULL, false);
7127 }
7128
7129 FreeWinUi();
7130 FreeCedar();
7131 break;
7132
7133 case SVC_MODE_TRAFFIC:
7134 // Communication throughput measurement tool
7135 InitCedar();
7136 InitWinUi(service_title_uni, NULL, 0);
7137 CmTraffic(NULL);
7138 FreeWinUi();
7139 FreeCedar();
7140 break;
7141
7142 case SVC_MODE_UIHELP:
7143 // Starting the UI Helper
7144 CnStart();
7145 break;
7146 }
7147
7148 }
7149 FreeToken(t);
7150 UniFreeToken(ut);
7151
7152 if (restoreReg)
7153 {
7154 MsWriteCallingServiceManagerProcessId(service_name, 0);
7155 }
7156 }
7157
7158 FreeMayaqua();
7159
7160 return 0;
7161 }
7162
7163 // Get the user name of the specified session
MsGetSessionUserName(UINT session_id)7164 wchar_t *MsGetSessionUserName(UINT session_id)
7165 {
7166 if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())
7167 {
7168 wchar_t *ret;
7169 wchar_t *name;
7170 UINT size = 0;
7171 if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id,
7172 WTSUserName, (wchar_t *)&name, &size) == false)
7173 {
7174 return NULL;
7175 }
7176
7177 if (name == NULL || UniStrLen(name) == 0)
7178 {
7179 ret = NULL;
7180 }
7181 else
7182 {
7183 ret = UniCopyStr(name);
7184 }
7185
7186 ms->nt->WTSFreeMemory(name);
7187
7188 return ret;
7189 }
7190 return NULL;
7191 }
7192
7193 // Get whether the current desktop is available for the VNC
MsIsCurrentDesktopAvailableForVnc()7194 bool MsIsCurrentDesktopAvailableForVnc()
7195 {
7196 if (MsIsNt() == false)
7197 {
7198 return true;
7199 }
7200
7201 if (MsIsCurrentTerminalSessionActive() == false)
7202 {
7203 return false;
7204 }
7205
7206 if (ms->nt->OpenDesktopA == NULL ||
7207 ms->nt->CloseDesktop == NULL ||
7208 ms->nt->SwitchDesktop == NULL)
7209 {
7210 return true;
7211 }
7212 else
7213 {
7214 HDESK hDesk = ms->nt->OpenDesktopA("default", 0, false, DESKTOP_SWITCHDESKTOP);
7215 bool ret;
7216
7217 if (hDesk == NULL)
7218 {
7219 return false;
7220 }
7221
7222 ret = ms->nt->SwitchDesktop(hDesk);
7223 ms->nt->CloseDesktop(hDesk);
7224
7225 return ret;
7226 }
7227 }
7228
7229 // Get whether the current terminal session is active
MsIsCurrentTerminalSessionActive()7230 bool MsIsCurrentTerminalSessionActive()
7231 {
7232 return MsIsTerminalSessionActive(MsGetCurrentTerminalSessionId());
7233 }
7234
7235 // Get whether the specified terminal session is active
MsIsTerminalSessionActive(UINT session_id)7236 bool MsIsTerminalSessionActive(UINT session_id)
7237 {
7238 if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())
7239 {
7240 UINT *status = NULL;
7241 UINT size = sizeof(status);
7242 bool active = true;
7243
7244 if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id,
7245 WTSConnectState, (wchar_t *)&status, &size) == false)
7246 {
7247 return true;
7248 }
7249
7250 switch (*status)
7251 {
7252 case WTSDisconnected:
7253 case WTSShadow:
7254 case WTSIdle:
7255 case WTSDown:
7256 case WTSReset:
7257 active = false;
7258 break;
7259 }
7260
7261 ms->nt->WTSFreeMemory(status);
7262
7263 return active;
7264 }
7265
7266 return true;
7267 }
7268
7269 // Get the current terminal session ID
MsGetCurrentTerminalSessionId()7270 UINT MsGetCurrentTerminalSessionId()
7271 {
7272 if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())
7273 {
7274 UINT ret;
7275 UINT *session_id = NULL;
7276 UINT size = sizeof(session_id);
7277 if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION,
7278 WTSSessionId, (wchar_t *)&session_id, &size) == false)
7279 {
7280 return 0;
7281 }
7282
7283 ret = *session_id;
7284
7285 ms->nt->WTSFreeMemory(session_id);
7286
7287 return ret;
7288 }
7289
7290 return 0;
7291 }
7292
7293 // Examine whether the Terminal Services is installed and the multiple sessions can log in
MsIsTerminalServiceMultiUserInstalled()7294 bool MsIsTerminalServiceMultiUserInstalled()
7295 {
7296 OS_INFO *info = GetOsInfo();
7297 OSVERSIONINFOEX i;
7298 if (MsIsTerminalServiceInstalled() == false)
7299 {
7300 return false;
7301 }
7302
7303 if (OS_IS_SERVER(info->OsType) == false)
7304 {
7305 return false;
7306 }
7307
7308 Zero(&i, sizeof(i));
7309 i.dwOSVersionInfoSize = sizeof(i);
7310 if (GetVersionEx((OSVERSIONINFO *)&i) == false)
7311 {
7312 return false;
7313 }
7314
7315 if (i.wSuiteMask & VER_SUITE_SINGLEUSERTS)
7316 {
7317 return false;
7318 }
7319
7320 return true;
7321 }
7322
7323 // Examine whether the user switching is installed
MsIsUserSwitchingInstalled()7324 bool MsIsUserSwitchingInstalled()
7325 {
7326 OS_INFO *info = GetOsInfo();
7327 OSVERSIONINFOEX i;
7328
7329 if (OS_IS_WINDOWS_NT(info->OsType) == false)
7330 {
7331 return false;
7332 }
7333
7334 if (ms->nt->WTSDisconnectSession == NULL ||
7335 ms->nt->WTSFreeMemory == NULL ||
7336 ms->nt->WTSQuerySessionInformation == NULL)
7337 {
7338 return false;
7339 }
7340
7341 if (GET_KETA(info->OsType, 100) < 2)
7342 {
7343 return false;
7344 }
7345
7346 Zero(&i, sizeof(i));
7347 i.dwOSVersionInfoSize = sizeof(i);
7348 if (GetVersionEx((OSVERSIONINFO *)&i) == false)
7349 {
7350 return false;
7351 }
7352
7353 if (i.wSuiteMask & VER_SUITE_SINGLEUSERTS)
7354 {
7355 return true;
7356 }
7357
7358 return false;
7359 }
7360
7361 // Enable the remote desktop
MsEnableRemoteDesktop()7362 bool MsEnableRemoteDesktop()
7363 {
7364 OS_INFO *info = GetOsInfo();
7365
7366 if (MsIsRemoteDesktopAvailable() == false)
7367 {
7368 return false;
7369 }
7370
7371 if (MsIsRemoteDesktopEnabled())
7372 {
7373 return true;
7374 }
7375
7376 if (GET_KETA(info->OsType, 100) == 2)
7377 {
7378 // Windows 2000
7379 return false;
7380 }
7381
7382 if (MsRegWriteInt(REG_LOCAL_MACHINE,
7383 "SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
7384 "fDenyTSConnections", 0) == false)
7385 {
7386 return false;
7387 }
7388
7389 if (MsIsVista())
7390 {
7391 if (MsRegWriteInt(REG_LOCAL_MACHINE,
7392 "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp",
7393 "UserAuthentication", 0) == false)
7394 {
7395 return false;
7396 }
7397 }
7398
7399 return true;
7400 }
7401
7402 // Examine whether the Remote Desktop is enabled
MsIsRemoteDesktopEnabled()7403 bool MsIsRemoteDesktopEnabled()
7404 {
7405 OS_INFO *info = GetOsInfo();
7406
7407 if (MsIsRemoteDesktopAvailable() == false)
7408 {
7409 return false;
7410 }
7411
7412 if (GET_KETA(info->OsType, 100) == 2)
7413 {
7414 // Windows 2000
7415 return MsIsServiceRunning("TermService");
7416 }
7417 else
7418 {
7419 // Windows XP or later
7420 bool b = MsRegReadInt(REG_LOCAL_MACHINE,
7421 "SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
7422 "fDenyTSConnections");
7423
7424 if (MsIsVista() == false)
7425 {
7426 return b ? false : true;
7427 }
7428 else
7429 {
7430 if (b)
7431 {
7432 return false;
7433 }
7434 else
7435 {
7436 if (MsRegReadInt(REG_LOCAL_MACHINE,
7437 "SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp",
7438 "UserAuthentication"))
7439 {
7440 return false;
7441 }
7442 else
7443 {
7444 return true;
7445 }
7446 }
7447 }
7448 }
7449 }
7450
7451 // Examine whether the remote desktop becomes available by registry operation
MsIsRemoteDesktopCanEnableByRegistory()7452 bool MsIsRemoteDesktopCanEnableByRegistory()
7453 {
7454 OS_INFO *info = GetOsInfo();
7455 if (MsIsRemoteDesktopAvailable() == false)
7456 {
7457 return false;
7458 }
7459
7460 if (GET_KETA(info->OsType, 100) == 2)
7461 {
7462 // Windows 2000
7463 return false;
7464 }
7465 else
7466 {
7467 // Others
7468 return true;
7469 }
7470 }
7471
7472 // Examine whether it's running on Windows 2000
MsIsWin2000()7473 bool MsIsWin2000()
7474 {
7475 OS_INFO *info = GetOsInfo();
7476
7477 if (OS_IS_WINDOWS_NT(info->OsType) == false)
7478 {
7479 return false;
7480 }
7481
7482 if (GET_KETA(info->OsType, 100) == 2)
7483 {
7484 return true;
7485 }
7486
7487 return false;
7488 }
7489
7490 // Examine whether Windows 2000 or later
MsIsWin2000OrGreater()7491 bool MsIsWin2000OrGreater()
7492 {
7493 OS_INFO *info = GetOsInfo();
7494
7495 if (OS_IS_WINDOWS_NT(info->OsType) == false)
7496 {
7497 return false;
7498 }
7499
7500 if (GET_KETA(info->OsType, 100) >= 2)
7501 {
7502 return true;
7503 }
7504
7505 return false;
7506 }
7507
7508 // Examine whether Windows XP or later
MsIsWinXPOrGreater()7509 bool MsIsWinXPOrGreater()
7510 {
7511 OS_INFO *info = GetOsInfo();
7512
7513 if (OS_IS_WINDOWS_NT(info->OsType) == false)
7514 {
7515 return false;
7516 }
7517
7518 if (GET_KETA(info->OsType, 100) >= 3)
7519 {
7520 return true;
7521 }
7522
7523 return false;
7524 }
7525
7526 // Examine whether the remote desktop is available
MsIsRemoteDesktopAvailable()7527 bool MsIsRemoteDesktopAvailable()
7528 {
7529 OS_INFO *info = GetOsInfo();
7530 if (MsIsTerminalServiceInstalled() == false)
7531 {
7532 return false;
7533 }
7534
7535 if (GET_KETA(info->OsType, 100) == 2)
7536 {
7537 // Windows 2000
7538 if (info->OsType == 2200)
7539 {
7540 // Windows 2000 Professional
7541 return false;
7542 }
7543 else
7544 {
7545 // Windows 2000 server series
7546 return true;
7547 }
7548 }
7549 else if (GET_KETA(info->OsType, 100) == 3)
7550 {
7551 // Windows XP
7552 if (info->OsType == OSTYPE_WINDOWS_XP_HOME)
7553 {
7554 // Home Edition
7555 return false;
7556 }
7557 else
7558 {
7559 // Professional Edition
7560 return true;
7561 }
7562 }
7563 else if (GET_KETA(info->OsType, 100) == 4)
7564 {
7565 // Windows Server 2003
7566 return true;
7567 }
7568 else if (GET_KETA(info->OsType, 100) >= 5)
7569 {
7570 // Windows Vista or later
7571 OSVERSIONINFOEX i;
7572
7573 Zero(&i, sizeof(i));
7574 i.dwOSVersionInfoSize = sizeof(i);
7575 if (GetVersionEx((OSVERSIONINFO *)&i) == false)
7576 {
7577 return false;
7578 }
7579
7580 if (i.wSuiteMask & VER_SUITE_PERSONAL)
7581 {
7582 // Home series
7583 return false;
7584 }
7585 else
7586 {
7587 return true;
7588 }
7589 }
7590
7591 return false;
7592 }
7593
7594 // Examine whether the Terminal Services is installed
MsIsTerminalServiceInstalled()7595 bool MsIsTerminalServiceInstalled()
7596 {
7597 OS_INFO *info = GetOsInfo();
7598 OSVERSIONINFOEX i;
7599
7600 if (OS_IS_WINDOWS_NT(info->OsType) == false)
7601 {
7602 return false;
7603 }
7604
7605 if (ms->nt->WTSDisconnectSession == NULL ||
7606 ms->nt->WTSFreeMemory == NULL ||
7607 ms->nt->WTSQuerySessionInformation == NULL)
7608 {
7609 return false;
7610 }
7611
7612 if (GET_KETA(info->OsType, 100) < 2)
7613 {
7614 return false;
7615 }
7616
7617 Zero(&i, sizeof(i));
7618 i.dwOSVersionInfoSize = sizeof(i);
7619 if (GetVersionEx((OSVERSIONINFO *)&i) == false)
7620 {
7621 return false;
7622 }
7623
7624 if (i.wSuiteMask & VER_SUITE_TERMINAL || i.wSuiteMask & VER_SUITE_SINGLEUSERTS)
7625 {
7626 return true;
7627 }
7628
7629 return false;
7630 }
7631
7632 // Stop the service
MsStopService(char * name)7633 bool MsStopService(char *name)
7634 {
7635 SC_HANDLE sc, service;
7636 bool ret = false;
7637 // Validate arguments
7638 if (name == NULL)
7639 {
7640 return false;
7641 }
7642 if (ms->IsNt == false)
7643 {
7644 return false;
7645 }
7646
7647 sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
7648 if (sc == NULL)
7649 {
7650 return false;
7651 }
7652
7653 service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
7654 if (service != NULL)
7655 {
7656 SERVICE_STATUS st;
7657 ret = ms->nt->ControlService(service, SERVICE_CONTROL_STOP, &st);
7658
7659 ms->nt->CloseServiceHandle(service);
7660 }
7661
7662 if (ret)
7663 {
7664 UINT64 end = Tick64() + 10000ULL;
7665 while (Tick64() < end)
7666 {
7667 if (MsIsServiceRunning(name) == false)
7668 {
7669 break;
7670 }
7671
7672 SleepThread(250);
7673 }
7674 }
7675
7676 ms->nt->CloseServiceHandle(sc);
7677 return ret;
7678 }
7679
7680 // Start the service
MsStartService(char * name)7681 bool MsStartService(char *name)
7682 {
7683 return MsStartServiceEx(name, NULL);
7684 }
MsStartServiceEx(char * name,UINT * error_code)7685 bool MsStartServiceEx(char *name, UINT *error_code)
7686 {
7687 SC_HANDLE sc, service;
7688 bool ret = false;
7689 static UINT dummy = 0;
7690 // Validate arguments
7691 if (name == NULL)
7692 {
7693 return false;
7694 }
7695 if (ms->IsNt == false)
7696 {
7697 return false;
7698 }
7699 if (error_code == NULL)
7700 {
7701 error_code = &dummy;
7702 }
7703
7704 *error_code = 0;
7705
7706 sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
7707 if (sc == NULL)
7708 {
7709 *error_code = GetLastError();
7710 return false;
7711 }
7712
7713 service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
7714 if (service != NULL)
7715 {
7716 ret = ms->nt->StartService(service, 0, NULL);
7717
7718 ms->nt->CloseServiceHandle(service);
7719 }
7720 else
7721 {
7722 *error_code = GetLastError();
7723 }
7724
7725 if (ret)
7726 {
7727 UINT64 end = Tick64() + 10000ULL;
7728 while (Tick64() < end)
7729 {
7730 if (MsIsServiceRunning(name))
7731 {
7732 break;
7733 }
7734
7735 SleepThread(250);
7736 }
7737 }
7738
7739 ms->nt->CloseServiceHandle(sc);
7740 return ret;
7741 }
7742
7743 // Get whether the service is running
MsIsServiceRunning(char * name)7744 bool MsIsServiceRunning(char *name)
7745 {
7746 SC_HANDLE sc, service;
7747 bool ret = false;
7748 // Validate arguments
7749 if (name == NULL || IsEmptyStr(name))
7750 {
7751 return false;
7752 }
7753 if (ms->IsNt == false)
7754 {
7755 return false;
7756 }
7757
7758 sc = ms->nt->OpenSCManager(NULL, NULL, GENERIC_READ);
7759 if (sc == NULL)
7760 {
7761 return false;
7762 }
7763
7764 service = ms->nt->OpenService(sc, name, GENERIC_READ);
7765 if (service != NULL)
7766 {
7767 SERVICE_STATUS st;
7768 Zero(&st, sizeof(st));
7769 if (ms->nt->QueryServiceStatus(service, &st))
7770 {
7771 switch (st.dwCurrentState)
7772 {
7773 case SERVICE_CONTINUE_PENDING:
7774 case SERVICE_PAUSE_PENDING:
7775 case SERVICE_PAUSED:
7776 case SERVICE_RUNNING:
7777 case SERVICE_START_PENDING:
7778 case SERVICE_STOP_PENDING:
7779 ret = true;
7780 break;
7781 }
7782 }
7783
7784 ms->nt->CloseServiceHandle(service);
7785 }
7786
7787 ms->nt->CloseServiceHandle(sc);
7788 return ret;
7789 }
7790
7791 // Uninstall the service
MsUninstallService(char * name)7792 bool MsUninstallService(char *name)
7793 {
7794 SC_HANDLE sc, service;
7795 bool ret = false;
7796 // Validate arguments
7797 if (name == NULL)
7798 {
7799 return false;
7800 }
7801 if (ms->IsNt == false)
7802 {
7803 return false;
7804 }
7805
7806 MsStopService(name);
7807
7808 sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
7809 if (sc == NULL)
7810 {
7811 return false;
7812 }
7813
7814 service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
7815 if (service != NULL)
7816 {
7817 if (ms->nt->DeleteService(service))
7818 {
7819 ret = true;
7820 }
7821 ms->nt->CloseServiceHandle(service);
7822 }
7823
7824 ms->nt->CloseServiceHandle(sc);
7825
7826 if (ret)
7827 {
7828 SleepThread(2000);
7829 }
7830
7831 return ret;
7832 }
7833
7834 // Update the title and description of the service
MsSetServiceDescription(char * name,wchar_t * description)7835 bool MsSetServiceDescription(char *name, wchar_t *description)
7836 {
7837 SC_HANDLE sc, service;
7838 // Validate arguments
7839 if (name == NULL || description == NULL)
7840 {
7841 return false;
7842 }
7843
7844 sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
7845 if (sc == NULL)
7846 {
7847 return false;
7848 }
7849
7850 service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
7851 if (service != NULL)
7852 {
7853 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
7854 {
7855 SERVICE_DESCRIPTIONW d;
7856
7857 if (UniIsEmptyStr(description) == false)
7858 {
7859 Zero(&d, sizeof(d));
7860 d.lpDescription = description;
7861 ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &d);
7862 }
7863 }
7864
7865 ms->nt->CloseServiceHandle(service);
7866 }
7867
7868 ms->nt->CloseServiceHandle(sc);
7869
7870 return true;
7871 }
7872
7873 // Update the service setting
MsUpdateServiceConfig(char * name)7874 bool MsUpdateServiceConfig(char *name)
7875 {
7876 SC_HANDLE sc, service;
7877 // Validate arguments
7878 if (name == NULL)
7879 {
7880 return false;
7881 }
7882
7883 // Whether just after Windows startup (deadlock prevention)
7884 if (timeGetTime() <= (60 * 30 * 1000))
7885 {
7886 if (MsRegReadInt(REG_LOCAL_MACHINE, "Software\\" GC_REG_COMPANY_NAME "\\Update Service Config", name) != 0)
7887 {
7888 return false;
7889 }
7890 }
7891
7892 sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
7893 if (sc == NULL)
7894 {
7895 return false;
7896 }
7897
7898 service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
7899 if (service != NULL)
7900 {
7901 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
7902 {
7903 SERVICE_FAILURE_ACTIONS action;
7904 SC_ACTION *e;
7905 Zero(&action, sizeof(action));
7906 e = ZeroMalloc(sizeof(SC_ACTION) * 3);
7907 e[0].Delay = 10000; e[0].Type = SC_ACTION_RESTART;
7908 e[1].Delay = 10000; e[1].Type = SC_ACTION_RESTART;
7909 e[2].Delay = 10000; e[2].Type = SC_ACTION_RESTART;
7910 action.cActions = 3;
7911 action.lpsaActions = e;
7912 action.dwResetPeriod = 1 * 60 * 60 * 24;
7913 ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &action);
7914
7915 MsRegWriteInt(REG_LOCAL_MACHINE, "Software\\" GC_REG_COMPANY_NAME "\\Update Service Config", name, 1);
7916 }
7917
7918
7919 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
7920 {
7921 SERVICE_DESCRIPTIONW d;
7922 wchar_t *description;
7923 char dname[MAX_SIZE];
7924
7925 Format(dname, sizeof(dname), "SVC_%s_DESCRIPT", name);
7926
7927 description = _UU(dname);
7928
7929 if (UniIsEmptyStr(description) == false)
7930 {
7931 Zero(&d, sizeof(d));
7932 d.lpDescription = description;
7933 ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &d);
7934 }
7935 }
7936
7937 ms->nt->CloseServiceHandle(service);
7938 }
7939
7940 ms->nt->CloseServiceHandle(sc);
7941
7942 return true;
7943 }
7944
7945 // Install the device driver
MsInstallDeviceDriverW(char * name,wchar_t * title,wchar_t * path,UINT * error_code)7946 bool MsInstallDeviceDriverW(char *name, wchar_t *title, wchar_t *path, UINT *error_code)
7947 {
7948 SC_HANDLE sc, service;
7949 bool ret = false;
7950 wchar_t name_w[MAX_SIZE];
7951 static UINT temp_int = 0;
7952 // Validate arguments
7953 if (name == NULL || title == NULL || path == NULL)
7954 {
7955 return false;
7956 }
7957 if (ms->IsNt == false)
7958 {
7959 return false;
7960 }
7961 if (error_code == NULL)
7962 {
7963 error_code = &temp_int;
7964 }
7965
7966 *error_code = 0;
7967
7968 StrToUni(name_w, sizeof(name_w), name);
7969
7970 sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
7971 if (sc == NULL)
7972 {
7973 *error_code = GetLastError();
7974 return false;
7975 }
7976
7977 service = ms->nt->CreateServiceW(sc, name_w, title, SERVICE_ALL_ACCESS,
7978 SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
7979 SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL);
7980
7981 if (service != NULL)
7982 {
7983 ret = true;
7984
7985 ms->nt->CloseServiceHandle(service);
7986 }
7987 else
7988 {
7989 *error_code = GetLastError();
7990 }
7991
7992 ms->nt->CloseServiceHandle(sc);
7993
7994 if (ret)
7995 {
7996 SleepThread(2000);
7997 }
7998
7999 return ret;
8000 }
8001
8002 // Install the service
MsInstallService(char * name,char * title,wchar_t * description,char * path)8003 bool MsInstallService(char *name, char *title, wchar_t *description, char *path)
8004 {
8005 wchar_t title_w[MAX_PATH];
8006 wchar_t path_w[MAX_PATH];
8007 // Validate arguments
8008 if (name == NULL || title == NULL || path == NULL)
8009 {
8010 return false;
8011 }
8012
8013 StrToUni(title_w, sizeof(title_w), title);
8014 StrToUni(path_w, sizeof(path_w), path);
8015
8016 return MsInstallServiceW(name, title_w, description, path_w);
8017 }
MsInstallServiceW(char * name,wchar_t * title,wchar_t * description,wchar_t * path)8018 bool MsInstallServiceW(char *name, wchar_t *title, wchar_t *description, wchar_t *path)
8019 {
8020 return MsInstallServiceExW(name, title, description, path, NULL);
8021 }
MsInstallServiceExW(char * name,wchar_t * title,wchar_t * description,wchar_t * path,UINT * error_code)8022 bool MsInstallServiceExW(char *name, wchar_t *title, wchar_t *description, wchar_t *path, UINT *error_code)
8023 {
8024 SC_HANDLE sc, service;
8025 bool ret = false;
8026 wchar_t name_w[MAX_SIZE];
8027 static UINT temp_int = 0;
8028 // Validate arguments
8029 if (name == NULL || title == NULL || path == NULL)
8030 {
8031 return false;
8032 }
8033 if (ms->IsNt == false)
8034 {
8035 return false;
8036 }
8037 if (error_code == NULL)
8038 {
8039 error_code = &temp_int;
8040 }
8041
8042 *error_code = 0;
8043
8044 StrToUni(name_w, sizeof(name_w), name);
8045
8046 sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
8047 if (sc == NULL)
8048 {
8049 *error_code = GetLastError();
8050 return false;
8051 }
8052
8053 service = ms->nt->CreateServiceW(sc, name_w, title, SERVICE_ALL_ACCESS,
8054 SERVICE_WIN32_OWN_PROCESS | (MsIsVista() ? 0 : SERVICE_INTERACTIVE_PROCESS), SERVICE_AUTO_START,
8055 SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL);
8056
8057 if (service != NULL)
8058 {
8059 ret = true;
8060
8061 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
8062 {
8063 SERVICE_DESCRIPTIONW d;
8064 SERVICE_FAILURE_ACTIONS action;
8065 SC_ACTION *e;
8066 Zero(&d, sizeof(d));
8067 d.lpDescription = description;
8068 ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &d);
8069 Zero(&action, sizeof(action));
8070 e = ZeroMalloc(sizeof(SC_ACTION) * 3);
8071 e[0].Delay = 10000; e[0].Type = SC_ACTION_RESTART;
8072 e[1].Delay = 10000; e[1].Type = SC_ACTION_RESTART;
8073 e[2].Delay = 10000; e[2].Type = SC_ACTION_RESTART;
8074 action.cActions = 3;
8075 action.lpsaActions = e;
8076 action.dwResetPeriod = 1 * 60 * 60 * 24;
8077 ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &action);
8078
8079 Free(e);
8080 }
8081
8082 ms->nt->CloseServiceHandle(service);
8083 }
8084 else
8085 {
8086 *error_code = GetLastError();
8087 }
8088
8089 ms->nt->CloseServiceHandle(sc);
8090
8091 if (ret)
8092 {
8093 SleepThread(2000);
8094 }
8095
8096 return ret;
8097 }
8098
8099 // Check whether the specified service is installed
MsIsServiceInstalled(char * name)8100 bool MsIsServiceInstalled(char *name)
8101 {
8102 SC_HANDLE sc;
8103 SC_HANDLE service;
8104 bool ret = false;
8105 // Validate arguments
8106 if (name == NULL)
8107 {
8108 return false;
8109 }
8110 if (ms->IsNt == false)
8111 {
8112 return false;
8113 }
8114
8115 sc = ms->nt->OpenSCManager(NULL, NULL, GENERIC_READ);
8116 if (sc == NULL)
8117 {
8118 return false;
8119 }
8120
8121 service = ms->nt->OpenService(sc, name, GENERIC_READ);
8122 if (service != NULL)
8123 {
8124 ret = true;
8125 }
8126
8127 ms->nt->CloseServiceHandle(service);
8128 ms->nt->CloseServiceHandle(sc);
8129
8130 return ret;
8131 }
8132
8133 // Kill the process
MsTerminateProcess()8134 void MsTerminateProcess()
8135 {
8136 TerminateProcess(GetCurrentProcess(), 0);
8137 _exit(0);
8138 }
8139
8140 // Get the Process ID
MsGetProcessId()8141 UINT MsGetProcessId()
8142 {
8143 return GetCurrentProcessId();
8144 }
8145
8146 // Get the MS structure
MsGetMs()8147 MS *MsGetMs()
8148 {
8149 return ms;
8150 }
8151
8152 // Lower the priority of the thread to lowest
MsSetThreadPriorityIdle()8153 void MsSetThreadPriorityIdle()
8154 {
8155 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
8156 }
8157
8158 // Raise the priority of a thread
MsSetThreadPriorityHigh()8159 void MsSetThreadPriorityHigh()
8160 {
8161 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
8162 }
8163
8164 // Lower the priority of the thread
MsSetThreadPriorityLow()8165 void MsSetThreadPriorityLow()
8166 {
8167 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
8168 }
8169
8170 // Raise the priority of the thread to highest
MsSetThreadPriorityRealtime()8171 void MsSetThreadPriorityRealtime()
8172 {
8173 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
8174 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
8175 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
8176 }
8177
8178 // Restore the priority of the thread
MsRestoreThreadPriority()8179 void MsRestoreThreadPriority()
8180 {
8181 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
8182 }
8183
8184 // Check whether should show the TCP setting application
MsIsShouldShowTcpConfigApp()8185 bool MsIsShouldShowTcpConfigApp()
8186 {
8187 MS_TCP tcp1, tcp2;
8188 if (MsIsTcpConfigSupported() == false)
8189 {
8190 return false;
8191 }
8192
8193 MsGetTcpConfig(&tcp1);
8194 if (MsLoadTcpConfigReg(&tcp2) == false)
8195 {
8196 return true;
8197 }
8198
8199 if (Cmp(&tcp1, &tcp2, sizeof(MS_TCP) != 0))
8200 {
8201 return true;
8202 }
8203
8204 return false;
8205 }
8206
8207 // Apply the temporary settings data of registry to the TCP parameter of the Windows
MsApplyTcpConfig()8208 void MsApplyTcpConfig()
8209 {
8210 if (MsIsTcpConfigSupported())
8211 {
8212 MS_TCP tcp;
8213
8214 if (MsLoadTcpConfigReg(&tcp))
8215 {
8216 MsSetTcpConfig(&tcp);
8217 }
8218 }
8219 }
8220
8221 // Check whether the dynamic configuration of TCP is supported in current state
MsIsTcpConfigSupported()8222 bool MsIsTcpConfigSupported()
8223 {
8224 if (MsIsNt() && MsIsAdmin())
8225 {
8226 UINT type = GetOsInfo()->OsType;
8227
8228 if (GET_KETA(type, 100) >= 2)
8229 {
8230 return true;
8231 }
8232 }
8233
8234 return false;
8235 }
8236
8237 // Read the TCP settings from the registry setting
MsLoadTcpConfigReg(MS_TCP * tcp)8238 bool MsLoadTcpConfigReg(MS_TCP *tcp)
8239 {
8240 // Validate arguments
8241 if (tcp == NULL)
8242 {
8243 return false;
8244 }
8245
8246 if (MsIsNt())
8247 {
8248 Zero(tcp, sizeof(MS_TCP));
8249
8250 if (MsRegIsValueEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", true) == false ||
8251 MsRegIsValueEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", true) == false)
8252 {
8253 return false;
8254 }
8255
8256 tcp->RecvWindowSize = MsRegReadIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", true);
8257 tcp->SendWindowSize = MsRegReadIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", true);
8258
8259 return true;
8260 }
8261 else
8262 {
8263 return false;
8264 }
8265 }
8266
8267 // Remove the TCP settings from the registry
MsDeleteTcpConfigReg()8268 void MsDeleteTcpConfigReg()
8269 {
8270 if (MsIsNt() && MsIsAdmin())
8271 {
8272 MsRegDeleteKeyEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, true);
8273 }
8274 }
8275
8276 // Write the TCP settings to the registry setting
MsSaveTcpConfigReg(MS_TCP * tcp)8277 void MsSaveTcpConfigReg(MS_TCP *tcp)
8278 {
8279 // Validate arguments
8280 if (tcp == NULL)
8281 {
8282 return;
8283 }
8284
8285 if (MsIsNt() && MsIsAdmin())
8286 {
8287 MsRegWriteIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", tcp->RecvWindowSize, true);
8288 MsRegWriteIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", tcp->SendWindowSize, true);
8289 }
8290 }
8291
8292 // Get the current TCP settings
MsGetTcpConfig(MS_TCP * tcp)8293 void MsGetTcpConfig(MS_TCP *tcp)
8294 {
8295 // Validate arguments
8296 if (tcp == NULL)
8297 {
8298 return;
8299 }
8300
8301 Zero(tcp, sizeof(MS_TCP));
8302
8303 if (MsIsNt())
8304 {
8305 UINT v;
8306 // Initialize the network setting
8307 MsInitGlobalNetworkConfig();
8308
8309 // Read the value of TcpWindowSize or GlobalMaxTcpWindowSize if there is
8310 v = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "TcpWindowSize");
8311 tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, v);
8312
8313 v = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "GlobalMaxTcpWindowSize");
8314 tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, v);
8315
8316 v = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "DefaultReceiveWindow");
8317 tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, v);
8318
8319 // Read the value of DefaultSendWindow if there is
8320 tcp->SendWindowSize = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "DefaultSendWindow");
8321 }
8322 }
8323
8324 // Write the TCP settings
MsSetTcpConfig(MS_TCP * tcp)8325 void MsSetTcpConfig(MS_TCP *tcp)
8326 {
8327 // Validate arguments
8328 if (tcp == NULL)
8329 {
8330 return;
8331 }
8332
8333 if (MsIsNt() && MsIsAdmin())
8334 {
8335 bool window_scaling = false;
8336 UINT tcp1323opts;
8337
8338 if (tcp->RecvWindowSize >= 65536 || tcp->SendWindowSize >= 65536)
8339 {
8340 window_scaling = true;
8341 }
8342
8343 // Set the Tcp1323Opts
8344 tcp1323opts = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "Tcp1323Opts");
8345 if (window_scaling)
8346 {
8347 if (tcp1323opts == 0)
8348 {
8349 tcp1323opts = 1;
8350 }
8351 if (tcp1323opts == 2)
8352 {
8353 tcp1323opts = 3;
8354 }
8355 }
8356 else
8357 {
8358 if (tcp1323opts == 1)
8359 {
8360 tcp1323opts = 0;
8361 }
8362 if (tcp1323opts == 3)
8363 {
8364 tcp1323opts = 2;
8365 }
8366 }
8367 MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "Tcp1323Opts", tcp1323opts);
8368
8369 // Set the Receive Window
8370 if (tcp->RecvWindowSize == 0)
8371 {
8372 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
8373 "DefaultReceiveWindow");
8374 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
8375 "TcpWindowSize");
8376 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
8377 "GlobalMaxTcpWindowSize");
8378 }
8379 else
8380 {
8381 MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
8382 "DefaultReceiveWindow", tcp->RecvWindowSize);
8383 MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
8384 "TcpWindowSize", tcp->RecvWindowSize);
8385 MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
8386 "GlobalMaxTcpWindowSize", tcp->RecvWindowSize);
8387 }
8388
8389 // Setting the Send Window
8390 if (tcp->SendWindowSize == 0)
8391 {
8392 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
8393 "DefaultSendWindow");
8394 }
8395 else
8396 {
8397 MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
8398 "DefaultSendWindow", tcp->SendWindowSize);
8399 }
8400 }
8401 }
8402
8403 // Initialize the global network settings
MsInitGlobalNetworkConfig()8404 void MsInitGlobalNetworkConfig()
8405 {
8406 if (MsIsNt())
8407 {
8408 UINT current_window_size;
8409 current_window_size = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "TcpWindowSize");
8410
8411 if (current_window_size == 65535 || current_window_size == 5980160 ||
8412 current_window_size == 16777216 || current_window_size == 16777214)
8413 {
8414 // Remove the strange value which is written by older version of PacketiX VPN
8415 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
8416 "DefaultReceiveWindow");
8417 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
8418 "DefaultSendWindow");
8419 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
8420 "Tcp1323Opts");
8421 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
8422 "TcpWindowSize");
8423 MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
8424 "GlobalMaxTcpWindowSize");
8425
8426 // Set vpn_no_change = true
8427 MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "vpn_no_change", 1);
8428 MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "vpn_no_change", 1);
8429 }
8430 }
8431 else
8432 {
8433 if (MsRegReadInt(REG_LOCAL_MACHINE,
8434 "System\\CurrentControlSet\\Services\\VxD\\MSTCP",
8435 "packetix_no_optimize") == 0)
8436 {
8437 // Disable the DeadGWDetect
8438 MsRegWriteStr(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\MSTCP",
8439 "DeadGWDetect", "0");
8440 }
8441 }
8442
8443 MsApplyTcpConfig();
8444 }
8445
8446 // Process disabling other off-loading of network and others
MsDisableNetworkOffloadingEtc()8447 void MsDisableNetworkOffloadingEtc()
8448 {
8449 wchar_t netsh[MAX_SIZE];
8450 UINT exec_timeout = 10000;
8451 if (MsIsNt() == false)
8452 {
8453 return;
8454 }
8455
8456 // Get the path of netsh.exe
8457 CombinePathW(netsh, sizeof(netsh), MsGetSystem32DirW(), L"netsh.exe");
8458
8459 // Registry settings
8460 MsRegWriteIntEx2(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "DisableTaskOffload", 1, false, true);
8461 MsRegWriteIntEx2(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "TcpNumConnections", TCP_MAX_NUM_CONNECTIONS, false, true);
8462
8463 if (MsIsVista() == false)
8464 {
8465 // Windows Server 2003 or earlier
8466 MsRegWriteIntEx2(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "EnableRSS", 1, false, true);
8467 MsRegWriteIntEx2(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "EnableTCPChimney", 1, false, true);
8468 MsRegWriteIntEx2(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "EnableTCPA", 1, false, true);
8469
8470 Win32RunAndWaitProcess(netsh, L"netsh int ip set chimney disabled", true, true, exec_timeout);
8471 SleepThread(250);
8472 }
8473 else
8474 {
8475 // Windows Vista or later
8476 Win32RunAndWaitProcess(netsh, L"int ipv4 set global taskoffload=disabled", true, true, exec_timeout);
8477 SleepThread(250);
8478 Win32RunAndWaitProcess(netsh, L"int ipv6 set global taskoffload=disabled", true, true, exec_timeout);
8479 SleepThread(250);
8480 Win32RunAndWaitProcess(netsh, L"int tcp set global chimney=disabled", true, true, exec_timeout);
8481 SleepThread(250);
8482 }
8483 }
8484
8485 // Upgrade the virtual LAN card
MsUpgradeVLan(char * tag_name,char * connection_tag_name,char * instance_name,MS_DRIVER_VER * ver)8486 bool MsUpgradeVLan(char *tag_name, char *connection_tag_name, char *instance_name, MS_DRIVER_VER *ver)
8487 {
8488 bool ret;
8489
8490 Lock(vlan_lock);
8491 {
8492 ret = MsUpgradeVLanWithoutLock(tag_name, connection_tag_name, instance_name, ver);
8493 }
8494 Unlock(vlan_lock);
8495
8496 return ret;
8497 }
MsUpgradeVLanWithoutLock(char * tag_name,char * connection_tag_name,char * instance_name,MS_DRIVER_VER * ver)8498 bool MsUpgradeVLanWithoutLock(char *tag_name, char *connection_tag_name, char *instance_name, MS_DRIVER_VER *ver)
8499 {
8500 char hwid[MAX_PATH];
8501 wchar_t hwid_w[MAX_PATH];
8502 bool ret = false;
8503 UCHAR old_mac_address[6];
8504 char *s;
8505 // Validate arguments
8506 if (instance_name == NULL || tag_name == NULL || connection_tag_name == NULL || ver == NULL)
8507 {
8508 return false;
8509 }
8510
8511 if (MsIsNt() == false)
8512 {
8513 // Can not be upgraded in Windows 9x
8514 return false;
8515 }
8516
8517 if (MsIsInfCatalogRequired())
8518 {
8519 if (MsIsValidVLanInstanceNameForInfCatalog(instance_name) == false)
8520 {
8521 return false;
8522 }
8523
8524 StrUpper(instance_name);
8525 }
8526
8527 Zero(hwid, sizeof(hwid));
8528 Format(hwid, sizeof(hwid), DRIVER_DEVICE_ID_TAG, instance_name);
8529 StrToUni(hwid_w, sizeof(hwid_w), hwid);
8530
8531 // Examine whether the virtual LAN card with the specified name has already registered
8532 if (MsIsVLanExists(tag_name, instance_name) == false)
8533 {
8534 // Not registered
8535 return false;
8536 }
8537
8538 // Get the previous MAC address
8539 s = MsGetMacAddress(tag_name, instance_name);
8540 if (s == NULL)
8541 {
8542 Zero(old_mac_address, 6);
8543 }
8544 else
8545 {
8546 BUF *b;
8547 b = StrToBin(s);
8548 Free(s);
8549
8550 if (b->Size == 6)
8551 {
8552 Copy(old_mac_address, b->Buf, b->Size);
8553 }
8554 else
8555 {
8556 Zero(old_mac_address, 6);
8557 }
8558
8559 FreeBuf(b);
8560 }
8561
8562 ret = MsUninstallVLanWithoutLock(instance_name);
8563
8564 ret = MsInstallVLanWithoutLock(tag_name, connection_tag_name, instance_name, ver);
8565
8566 return ret;
8567 }
MsUpgradeVLanWithoutLock_old(char * tag_name,char * connection_tag_name,char * instance_name,MS_DRIVER_VER * ver)8568 bool MsUpgradeVLanWithoutLock_old(char *tag_name, char *connection_tag_name, char *instance_name, MS_DRIVER_VER *ver)
8569 {
8570 wchar_t infpath[MAX_PATH];
8571 char hwid[MAX_PATH];
8572 wchar_t hwid_w[MAX_PATH];
8573 bool ret = false;
8574 bool need_reboot;
8575 bool before_status;
8576 UCHAR old_mac_address[6];
8577 UCHAR new_mac_address[6];
8578 char *s;
8579 NO_WARNING *nw;
8580 char neo_sys[MAX_PATH];
8581 char *reg_key;
8582 UINT i;
8583 // Validate arguments
8584 if (instance_name == NULL || tag_name == NULL || connection_tag_name == NULL || ver == NULL)
8585 {
8586 return false;
8587 }
8588
8589 if (MsIsNt() == false)
8590 {
8591 // Can not be upgraded in Windows 9x
8592 return false;
8593 }
8594
8595 if (MsIsInfCatalogRequired())
8596 {
8597 if (MsIsValidVLanInstanceNameForInfCatalog(instance_name) == false)
8598 {
8599 return false;
8600 }
8601
8602 StrUpper(instance_name);
8603 }
8604
8605 Zero(hwid, sizeof(hwid));
8606 Format(hwid, sizeof(hwid), DRIVER_DEVICE_ID_TAG, instance_name);
8607 StrToUni(hwid_w, sizeof(hwid_w), hwid);
8608
8609 // Examine whether the virtual LAN card with the specified name has already registered
8610 if (MsIsVLanExists(tag_name, instance_name) == false)
8611 {
8612 // Not registered
8613 return false;
8614 }
8615
8616 reg_key = MsGetNetCfgRegKeyName(tag_name, instance_name);
8617
8618 if (IsEmptyStr(reg_key) == false)
8619 {
8620 // Add a value to the registry key
8621 MsRegWriteInt(REG_LOCAL_MACHINE, reg_key, "*IfType", 6);
8622 MsRegWriteInt(REG_LOCAL_MACHINE, reg_key, "*MediaType", 0);
8623 MsRegWriteInt(REG_LOCAL_MACHINE, reg_key, "*PhysicalMediaType", 0);
8624 }
8625 Free(reg_key);
8626
8627 // Get the .sys file name that is currently being used
8628 if (MsGetNeoDeiverFilename(neo_sys, sizeof(neo_sys), instance_name) == false)
8629 {
8630 if (MsIsInfCatalogRequired())
8631 {
8632 // Can not be upgraded if getting current .sys file name failed
8633 // in the Windows 8 or later
8634 return false;
8635 }
8636
8637 // Create a new file name because it is unknown
8638 if (MsMakeNewNeoDriverFilename(neo_sys, sizeof(neo_sys)) == false)
8639 {
8640 // Failure
8641 return false;
8642 }
8643 }
8644
8645 // Get the current operating status
8646 before_status = MsIsVLanEnabled(instance_name);
8647
8648 // Get the previous MAC address
8649 s = MsGetMacAddress(tag_name, instance_name);
8650 if (s == NULL)
8651 {
8652 Zero(old_mac_address, 6);
8653 }
8654 else
8655 {
8656 BUF *b;
8657 b = StrToBin(s);
8658 Free(s);
8659
8660 if (b->Size == 6)
8661 {
8662 Copy(old_mac_address, b->Buf, b->Size);
8663 }
8664 else
8665 {
8666 Zero(old_mac_address, 6);
8667 }
8668
8669 FreeBuf(b);
8670 }
8671
8672 // Starting the installation
8673 if (MsStartDriverInstall(instance_name, IsZero(old_mac_address, 6) ? NULL : old_mac_address, neo_sys,
8674 new_mac_address, ver) == false)
8675 {
8676 return false;
8677 }
8678 MsGetDriverPath(instance_name, NULL, NULL, infpath, NULL, NULL, NULL, neo_sys);
8679
8680 nw = NULL;
8681
8682 //if (MsIsVista() == false)
8683 {
8684 nw = MsInitNoWarning();
8685 }
8686
8687 // Do the installation
8688 if (ms->nt->UpdateDriverForPlugAndPlayDevicesW(
8689 NULL, hwid_w, infpath, 1, &need_reboot))
8690 {
8691 ret = true;
8692 }
8693 MsFreeNoWarning(nw);
8694
8695 // Installation complete
8696 MsFinishDriverInstall(instance_name, neo_sys);
8697
8698 for (i = 0;i < 5;i++)
8699 {
8700 MsInitNetworkConfig(tag_name, instance_name, connection_tag_name);
8701 if (MsIsInfCatalogRequired())
8702 {
8703 // Write the MAC address
8704 char mac_address_str[MAX_SIZE];
8705 BinToStr(mac_address_str, sizeof(mac_address_str), new_mac_address, sizeof(new_mac_address));
8706 MsSetMacAddress(VLAN_ADAPTER_NAME_TAG, instance_name, mac_address_str);
8707 }
8708
8709 SleepThread(MsIsVista() ? 1000 : 300);
8710 }
8711
8712 SleepThread(MsIsVista() ? 1000 : 300);
8713
8714 // Restore operation
8715 if (before_status)
8716 {
8717 MsEnableVLan(instance_name);
8718 }
8719 else
8720 {
8721 MsDisableVLan(instance_name);
8722 }
8723
8724 return ret;
8725 }
8726
8727 // Test for Windows 9x
MsWin9xTest()8728 void MsWin9xTest()
8729 {
8730 }
8731
8732 // Update the CompatibleIDs of virtual LAN card
MsUpdateCompatibleIDs(char * instance_name)8733 void MsUpdateCompatibleIDs(char *instance_name)
8734 {
8735 TOKEN_LIST *t;
8736 char id[MAX_SIZE];
8737 char device_title[MAX_SIZE];
8738 char device_title_old[MAX_SIZE];
8739 // Validate arguments
8740 if (instance_name == NULL)
8741 {
8742 return;
8743 }
8744
8745 Format(id, sizeof(id), DRIVER_DEVICE_ID_TAG, instance_name);
8746 Format(device_title, sizeof(device_title), VLAN_ADAPTER_NAME_TAG, instance_name);
8747 Format(device_title_old, sizeof(device_title_old), VLAN_ADAPTER_NAME_TAG_OLD, instance_name);
8748
8749 t = MsRegEnumKey(REG_LOCAL_MACHINE, "Enum\\Root\\Net");
8750 if (t != NULL)
8751 {
8752 UINT i;
8753 for (i = 0;i < t->NumTokens;i++)
8754 {
8755 char keyname[MAX_PATH];
8756 char *str;
8757 char *title;
8758
8759 Format(keyname, sizeof(keyname), "Enum\\Root\\Net\\%s", t->Token[i]);
8760
8761 title = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "DeviceDesc");
8762
8763 if (title != NULL)
8764 {
8765 if (StrCmpi(title, device_title) == 0 || StrCmpi(title, device_title_old) == 0)
8766 {
8767 Format(keyname, sizeof(keyname), "Enum\\Root\\Net\\%s",t->Token[i]);
8768 str = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "CompatibleIDs");
8769 if (str != NULL)
8770 {
8771 Free(str);
8772 }
8773 else
8774 {
8775 MsRegWriteStr(REG_LOCAL_MACHINE, keyname, "CompatibleIDs", id);
8776 }
8777 }
8778 Free(title);
8779 }
8780 }
8781
8782 FreeToken(t);
8783 }
8784
8785 MsRegWriteStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", "SourcePath",
8786 ms->System32Dir);
8787 }
8788
8789 // Installing the virtual LAN card (for Win9x)
MsInstallVLan9x(char * instance_name,MS_DRIVER_VER * ver)8790 bool MsInstallVLan9x(char *instance_name, MS_DRIVER_VER *ver)
8791 {
8792 char sysdir[MAX_PATH];
8793 char infdir[MAX_PATH];
8794 char otherdir[MAX_PATH];
8795 char syspath[MAX_PATH];
8796 char syspath2[MAX_PATH];
8797 char infpath[MAX_PATH];
8798 char vpn16[MAX_PATH];
8799 char infpath_src[MAX_PATH];
8800 char syspath_src[MAX_PATH];
8801 char neo_sys[MAX_PATH];
8802 // Validate arguments
8803 if (instance_name == NULL || ver == NULL)
8804 {
8805 return false;
8806 }
8807
8808 StrCpy(sysdir, sizeof(sysdir), MsGetSystem32Dir());
8809 Format(infdir, sizeof(infdir), "%s\\inf", MsGetWindowsDir());
8810 Format(otherdir, sizeof(otherdir), "%s\\other", infdir);
8811 Format(syspath, sizeof(syspath), "%s\\Neo_%s.sys", sysdir, instance_name);
8812 Format(syspath2, sizeof(syspath2), "%s\\Neo_%s.sys", infdir, instance_name);
8813 Format(infpath, sizeof(infpath), "%s\\Neo_%s.inf", infdir, instance_name);
8814 Format(vpn16, sizeof(vpn16), "%s\\vpn16.exe", MsGetMyTempDir());
8815
8816 MakeDir(otherdir);
8817
8818 Format(neo_sys, sizeof(neo_sys), "Neo_%s.sys", instance_name);
8819
8820 // Copy of vpn16.exe
8821 FileCopy("|vpn16.exe", vpn16);
8822
8823 // Starting the installation
8824 if (MsStartDriverInstall(instance_name, NULL, neo_sys, NULL, ver) == false)
8825 {
8826 return false;
8827 }
8828 MsGetDriverPathA(instance_name, NULL, NULL, infpath_src, syspath_src, NULL, NULL, neo_sys);
8829
8830 // Copy of the inf file
8831 FileCopy(infpath_src, infpath);
8832
8833 // Copy of the sys file
8834 FileCopy(syspath_src, syspath);
8835
8836 // Install the device driver
8837 if (Run(vpn16, instance_name, false, true) == false)
8838 {
8839 return false;
8840 }
8841
8842 // Update the CompatibleIDs
8843 MsUpdateCompatibleIDs(instance_name);
8844
8845 return true;
8846 }
8847
8848 // Child window enumeration procedure
MsEnumChildWindowProc(HWND hWnd,LPARAM lParam)8849 bool CALLBACK MsEnumChildWindowProc(HWND hWnd, LPARAM lParam)
8850 {
8851 LIST *o = (LIST *)lParam;
8852
8853 if (o != NULL)
8854 {
8855 MsEnumChildWindows(o, hWnd);
8856 }
8857
8858 return true;
8859 }
8860
8861 // Enumerate specified window and all the its child windows
MsEnumChildWindows(LIST * o,HWND hWnd)8862 LIST *MsEnumChildWindows(LIST *o, HWND hWnd)
8863 {
8864 // Validate arguments
8865 if (hWnd == NULL)
8866 {
8867 return NULL;
8868 }
8869
8870 if (o == NULL)
8871 {
8872 o = NewListFast(NULL);
8873 }
8874
8875 MsAddWindowToList(o, hWnd);
8876
8877 EnumChildWindows(hWnd, MsEnumChildWindowProc, (LPARAM)o);
8878
8879 return o;
8880 }
8881
8882 // Add a window to the list
MsAddWindowToList(LIST * o,HWND hWnd)8883 void MsAddWindowToList(LIST *o, HWND hWnd)
8884 {
8885 // Validate arguments
8886 if (o == NULL || hWnd == NULL)
8887 {
8888 return;
8889 }
8890
8891 if (IsInList(o, hWnd) == false)
8892 {
8893 Add(o, hWnd);
8894 }
8895 }
8896
8897 // Enumeration of the window that the thread owns
MsEnumThreadWindowProc(HWND hWnd,LPARAM lParam)8898 bool CALLBACK MsEnumThreadWindowProc(HWND hWnd, LPARAM lParam)
8899 {
8900 LIST *o = (LIST *)lParam;
8901
8902 if (o == NULL)
8903 {
8904 return false;
8905 }
8906
8907 MsEnumChildWindows(o, hWnd);
8908
8909 return true;
8910 }
8911
8912 // Window enumeration procedure
EnumTopWindowProc(HWND hWnd,LPARAM lParam)8913 BOOL CALLBACK EnumTopWindowProc(HWND hWnd, LPARAM lParam)
8914 {
8915 LIST *o = (LIST *)lParam;
8916 HWND hParent;
8917 char c1[MAX_SIZE], c2[MAX_SIZE];
8918 // Validate arguments
8919 if (hWnd == NULL || o == NULL)
8920 {
8921 return TRUE;
8922 }
8923
8924 Zero(c1, sizeof(c1));
8925 Zero(c2, sizeof(c2));
8926
8927 hParent = GetParent(hWnd);
8928
8929 GetClassName(hWnd, c1, sizeof(c1));
8930
8931 if (hParent != NULL)
8932 {
8933 GetClassName(hParent, c2, sizeof(c2));
8934 }
8935
8936 if (StrCmpi(c1, "SysIPAddress32") != 0 && (IsEmptyStr(c2) || StrCmpi(c2, "SysIPAddress32") != 0))
8937 {
8938 AddWindow(o, hWnd);
8939 }
8940
8941 return TRUE;
8942 }
8943
8944 // Child window enumeration procedure
EnumChildWindowProc(HWND hWnd,LPARAM lParam)8945 BOOL CALLBACK EnumChildWindowProc(HWND hWnd, LPARAM lParam)
8946 {
8947 ENUM_CHILD_WINDOW_PARAM *p = (ENUM_CHILD_WINDOW_PARAM *)lParam;
8948 LIST *o;
8949 HWND hParent;
8950 char c1[MAX_SIZE], c2[MAX_SIZE];
8951 bool ok = false;
8952 // Validate arguments
8953 if (hWnd == NULL || p == NULL)
8954 {
8955 return TRUE;
8956 }
8957
8958 o = p->o;
8959
8960 Zero(c1, sizeof(c1));
8961 Zero(c2, sizeof(c2));
8962
8963 hParent = GetParent(hWnd);
8964
8965 GetClassName(hWnd, c1, sizeof(c1));
8966
8967 if (hParent != NULL)
8968 {
8969 GetClassName(hParent, c2, sizeof(c2));
8970 }
8971
8972 if (p->include_ipcontrol || (StrCmpi(c1, "SysIPAddress32") != 0 && (IsEmptyStr(c2) || StrCmpi(c2, "SysIPAddress32") != 0)))
8973 {
8974 ok = true;
8975 }
8976
8977 if (MsIsWine())
8978 {
8979 if (StrCmpi(c1, "SysIPAddress32") == 0 || StrCmpi(c2, "SysIPAddress32") == 0)
8980 {
8981 ok = true;
8982 }
8983 }
8984
8985 if (ok)
8986 {
8987 AddWindow(o, hWnd);
8988
8989 if (p->no_recursion == false)
8990 {
8991 EnumChildWindows(hWnd, EnumChildWindowProc, (LPARAM)p);
8992 }
8993 }
8994
8995 return TRUE;
8996 }
EnumAllWindow()8997 LIST *EnumAllWindow()
8998 {
8999 return EnumAllWindowEx(false, false);
9000 }
EnumAllWindowEx(bool no_recursion,bool include_ipcontrol)9001 LIST *EnumAllWindowEx(bool no_recursion, bool include_ipcontrol)
9002 {
9003 ENUM_CHILD_WINDOW_PARAM p;
9004 LIST *o = NewWindowList();
9005
9006 Zero(&p, sizeof(p));
9007 p.o = o;
9008 p.no_recursion = no_recursion;
9009 p.include_ipcontrol = include_ipcontrol;
9010
9011 EnumWindows(EnumChildWindowProc, (LPARAM)&p);
9012
9013 return o;
9014 }
EnumAllTopWindow()9015 LIST *EnumAllTopWindow()
9016 {
9017 LIST *o = NewWindowList();
9018
9019 EnumWindows(EnumTopWindowProc, (LPARAM)o);
9020
9021 return o;
9022 }
9023
9024 // Enumerate the child windows of all that is in the specified window
EnumAllChildWindow(HWND hWnd)9025 LIST *EnumAllChildWindow(HWND hWnd)
9026 {
9027 return EnumAllChildWindowEx(hWnd, false, false, false);
9028 }
EnumAllChildWindowEx(HWND hWnd,bool no_recursion,bool include_ipcontrol,bool no_self)9029 LIST *EnumAllChildWindowEx(HWND hWnd, bool no_recursion, bool include_ipcontrol, bool no_self)
9030 {
9031 ENUM_CHILD_WINDOW_PARAM p;
9032 LIST *o = NewWindowList();
9033
9034 Zero(&p, sizeof(p));
9035 p.include_ipcontrol = include_ipcontrol;
9036 p.no_recursion = no_recursion;
9037 p.o = o;
9038
9039 if (no_self == false)
9040 {
9041 AddWindow(o, hWnd);
9042 }
9043
9044 EnumChildWindows(hWnd, EnumChildWindowProc, (LPARAM)&p);
9045
9046 return o;
9047 }
9048
9049 // Release of the window list
FreeWindowList(LIST * o)9050 void FreeWindowList(LIST *o)
9051 {
9052 UINT i;
9053 // Validate arguments
9054 if (o == NULL)
9055 {
9056 return;
9057 }
9058
9059 for (i = 0;i < LIST_NUM(o);i++)
9060 {
9061 HWND *e = LIST_DATA(o, i);
9062
9063 Free(e);
9064 }
9065
9066 ReleaseList(o);
9067 }
9068
9069 // Add a window to the window list
AddWindow(LIST * o,HWND hWnd)9070 void AddWindow(LIST *o, HWND hWnd)
9071 {
9072 HWND t, *e;
9073 // Validate arguments
9074 if (o == NULL || hWnd == NULL)
9075 {
9076 return;
9077 }
9078
9079 t = hWnd;
9080
9081 if (Search(o, &t) != NULL)
9082 {
9083 return;
9084 }
9085
9086 e = ZeroMalloc(sizeof(HWND));
9087 *e = hWnd;
9088
9089 Insert(o, e);
9090 }
9091
9092 // Comparison of the window list items
CmpWindowList(void * p1,void * p2)9093 int CmpWindowList(void *p1, void *p2)
9094 {
9095 HWND *h1, *h2;
9096 if (p1 == NULL || p2 == NULL)
9097 {
9098 return 0;
9099 }
9100 h1 = *(HWND **)p1;
9101 h2 = *(HWND **)p2;
9102 if (h1 == NULL || h2 == NULL)
9103 {
9104 return 0;
9105 }
9106
9107 return Cmp(h1, h2, sizeof(HWND));
9108 }
9109
9110 // Creating a new window list
NewWindowList()9111 LIST *NewWindowList()
9112 {
9113 return NewListFast(CmpWindowList);
9114 }
9115
9116 // Determine whether it's Windows Vista or later
MsIsVista()9117 bool MsIsVista()
9118 {
9119 OS_INFO *info = GetOsInfo();
9120
9121 if (info == NULL)
9122 {
9123 return false;
9124 }
9125
9126 if (OS_IS_WINDOWS_NT(info->OsType))
9127 {
9128 if (GET_KETA(info->OsType, 100) >= 5)
9129 {
9130 return true;
9131 }
9132 }
9133
9134 return false;
9135 }
9136
9137 // Determine whether it's Windows 7 or later
MsIsWindows7()9138 bool MsIsWindows7()
9139 {
9140 OS_INFO *info = GetOsInfo();
9141
9142 if (info == NULL)
9143 {
9144 return false;
9145 }
9146
9147 if (OS_IS_WINDOWS_NT(info->OsType))
9148 {
9149 if (GET_KETA(info->OsType, 100) >= 6)
9150 {
9151 return true;
9152 }
9153 }
9154
9155 return false;
9156 }
9157
9158 // Determine whether it's Windows 10 or later
MsIsWindows10()9159 bool MsIsWindows10()
9160 {
9161 OS_INFO *info = GetOsInfo();
9162
9163 if (info == NULL)
9164 {
9165 return false;
9166 }
9167
9168 if (OS_IS_WINDOWS_NT(info->OsType))
9169 {
9170 if (GET_KETA(info->OsType, 100) == 7)
9171 {
9172 if (GET_KETA(info->OsType, 1) >= 2)
9173 {
9174 return true;
9175 }
9176 }
9177
9178 if (GET_KETA(info->OsType, 100) >= 8)
9179 {
9180 return true;
9181 }
9182 }
9183
9184 return false;
9185 }
9186
9187 // Determine whether it's Windows 8.1 or later
MsIsWindows81()9188 bool MsIsWindows81()
9189 {
9190 OS_INFO *info = GetOsInfo();
9191
9192 if (info == NULL)
9193 {
9194 return false;
9195 }
9196
9197 if (OS_IS_WINDOWS_NT(info->OsType))
9198 {
9199 if (GET_KETA(info->OsType, 100) == 7)
9200 {
9201 if (GET_KETA(info->OsType, 1) >= 1)
9202 {
9203 return true;
9204 }
9205 }
9206
9207 if (GET_KETA(info->OsType, 100) >= 8)
9208 {
9209 return true;
9210 }
9211 }
9212
9213 return false;
9214 }
9215
9216 // Determine whether it's Windows 8 or later
MsIsWindows8()9217 bool MsIsWindows8()
9218 {
9219 OS_INFO *info = GetOsInfo();
9220
9221 if (info == NULL)
9222 {
9223 return false;
9224 }
9225
9226 if (OS_IS_WINDOWS_NT(info->OsType))
9227 {
9228 if (GET_KETA(info->OsType, 100) >= 7)
9229 {
9230 return true;
9231 }
9232 }
9233
9234 return false;
9235 }
9236
9237 // Whether INF catalog signature is required
MsIsInfCatalogRequired()9238 bool MsIsInfCatalogRequired()
9239 {
9240 return MsIsWindows8();
9241 }
9242
9243 // Get the process path of the owner of the window
MsGetWindowOwnerProcessExeName(char * path,UINT size,HWND hWnd)9244 bool MsGetWindowOwnerProcessExeName(char *path, UINT size, HWND hWnd)
9245 {
9246 DWORD procId = 0;
9247 // Validate arguments
9248 if (path == NULL || hWnd == NULL)
9249 {
9250 return false;
9251 }
9252
9253 GetWindowThreadProcessId(hWnd, &procId);
9254 if (procId == 0)
9255 {
9256 return false;
9257 }
9258
9259 if (MsGetProcessExeName(path, size, procId) == false)
9260 {
9261 return false;
9262 }
9263
9264 return true;
9265 }
MsGetWindowOwnerProcessExeNameW(wchar_t * path,UINT size,HWND hWnd)9266 bool MsGetWindowOwnerProcessExeNameW(wchar_t *path, UINT size, HWND hWnd)
9267 {
9268 DWORD procId = 0;
9269 // Validate arguments
9270 if (path == NULL || hWnd == NULL)
9271 {
9272 return false;
9273 }
9274
9275 GetWindowThreadProcessId(hWnd, &procId);
9276 if (procId == 0)
9277 {
9278 return false;
9279 }
9280
9281 if (MsGetProcessExeNameW(path, size, procId) == false)
9282 {
9283 return false;
9284 }
9285
9286 return true;
9287 }
9288
9289 // Get the process path from process ID
MsGetProcessExeName(char * path,UINT size,UINT id)9290 bool MsGetProcessExeName(char *path, UINT size, UINT id)
9291 {
9292 LIST *o;
9293 MS_PROCESS *proc;
9294 bool ret = false;
9295 // Validate arguments
9296 if (path == NULL)
9297 {
9298 return false;
9299 }
9300
9301 o = MsGetProcessList();
9302 proc = MsSearchProcessById(o, id);
9303
9304 if (proc != NULL)
9305 {
9306 ret = true;
9307 StrCpy(path, size, proc->ExeFilename);
9308 }
9309
9310 MsFreeProcessList(o);
9311
9312 return ret;
9313 }
MsGetProcessExeNameW(wchar_t * path,UINT size,UINT id)9314 bool MsGetProcessExeNameW(wchar_t *path, UINT size, UINT id)
9315 {
9316 LIST *o;
9317 MS_PROCESS *proc;
9318 bool ret = false;
9319 // Validate arguments
9320 if (path == NULL)
9321 {
9322 return false;
9323 }
9324
9325 o = MsGetProcessList();
9326 proc = MsSearchProcessById(o, id);
9327
9328 if (proc != NULL)
9329 {
9330 ret = true;
9331 UniStrCpy(path, size, proc->ExeFilenameW);
9332 }
9333
9334 MsFreeProcessList(o);
9335
9336 return ret;
9337 }
9338
9339 // Close the alert dialog
MsCloseWarningWindow(NO_WARNING * nw,UINT thread_id)9340 bool MsCloseWarningWindow(NO_WARNING *nw, UINT thread_id)
9341 {
9342 UINT i;
9343 LIST *o;
9344 bool ret = false;
9345 bool press = false;
9346
9347 if (MsIsVista() == false || nw->StartTimer == 0)
9348 {
9349 press = true;
9350 }
9351
9352 if (nw->StartTick != 0 && nw->StartTick <= Tick64())
9353 {
9354 press = true;
9355 }
9356
9357 if (MsIsVista() == false)
9358 {
9359 o = NewListFast(NULL);
9360 EnumThreadWindows(thread_id, MsEnumThreadWindowProc, (LPARAM)o);
9361 }
9362 else
9363 {
9364 o = EnumAllTopWindow();
9365 }
9366
9367 for (i = 0;i < LIST_NUM(o);i++)
9368 {
9369 HWND hWnd;
9370
9371 if (nw->Halt)
9372 {
9373 break;
9374 }
9375
9376 if (MsIsVista() == false)
9377 {
9378 hWnd = LIST_DATA(o, i);
9379 }
9380 else
9381 {
9382 hWnd = *((HWND *)LIST_DATA(o, i));
9383 }
9384
9385 if (hWnd != NULL)
9386 {
9387 OS_INFO *info = GetOsInfo();
9388
9389 if (MsIsNt())
9390 {
9391 // Get whether this window is a warning screen of driver
9392 if (MsIsVista() == false)
9393 {
9394 // Other than Windows Vista
9395 HWND hStatic, hOk, hCancel, hDetail;
9396
9397 hStatic = GetDlgItem(hWnd, 0x14C1);
9398 hOk = GetDlgItem(hWnd, 0x14B7);
9399 hCancel = GetDlgItem(hWnd, 0x14BA);
9400 hDetail = GetDlgItem(hWnd, 0x14B9);
9401
9402 if ((hStatic != NULL || hDetail != NULL) && hOk != NULL && hCancel != NULL)
9403 {
9404 char tmp[MAX_SIZE];
9405 bool b = false;
9406
9407 if (GetClassName(hStatic, tmp, sizeof(tmp)) != 0)
9408 {
9409 if (StrCmpi(tmp, "static") == 0)
9410 {
9411 b = true;
9412 }
9413 }
9414
9415 if (GetClassName(hDetail, tmp, sizeof(tmp)) != 0)
9416 {
9417 if (StrCmpi(tmp, "button") == 0)
9418 {
9419 b = true;
9420 }
9421 }
9422
9423 if (b)
9424 {
9425 if (GetClassName(hOk, tmp, sizeof(tmp)) != 0)
9426 {
9427 if (StrCmpi(tmp, "button") == 0)
9428 {
9429 if (GetClassName(hCancel, tmp, sizeof(tmp)) != 0)
9430 {
9431 if (StrCmpi(tmp, "button") == 0)
9432 {
9433 // Press the OK button since it was found
9434 PostMessage(hWnd, WM_COMMAND, 0x14B7, 0);
9435
9436 ret = true;
9437 }
9438 }
9439 }
9440 }
9441 }
9442 }
9443 }
9444 else
9445 {
9446 // Windows Vista
9447 char exe[MAX_PATH];
9448
9449 if (MsGetWindowOwnerProcessExeName(exe, sizeof(exe), hWnd))
9450 {
9451 if (EndWith(exe, "rundll32.exe"))
9452 {
9453 LIST *o;
9454 HWND h;
9455 UINT i;
9456
9457 o = EnumAllChildWindow(hWnd);
9458
9459 if (o != NULL)
9460 {
9461 for (i = 0;i < LIST_NUM(o);i++)
9462 {
9463 char tmp[MAX_SIZE];
9464
9465 h = *((HWND *)LIST_DATA(o, i));
9466
9467 Zero(tmp, sizeof(tmp));
9468 GetClassNameA(h, tmp, sizeof(tmp));
9469
9470 if (StrCmpi(tmp, "DirectUIHWND") == 0)
9471 {
9472 LIST *o = EnumAllChildWindow(h);
9473
9474 if (o != NULL)
9475 {
9476 UINT j;
9477 UINT numDirectUIHWND = 0;
9478 UINT numButton = 0;
9479 HWND hButton1 = NULL;
9480 HWND hButton2 = NULL;
9481
9482 for (j = 0;j < LIST_NUM(o);j++)
9483 {
9484 HWND hh;
9485 char tmp[MAX_SIZE];
9486
9487 hh = *((HWND *)LIST_DATA(o, j));
9488
9489 Zero(tmp, sizeof(tmp));
9490 GetClassNameA(hh, tmp, sizeof(tmp));
9491
9492 if (StrCmpi(tmp, "DirectUIHWND") == 0)
9493 {
9494 numDirectUIHWND++;
9495 }
9496
9497 if (StrCmpi(tmp, "button") == 0)
9498 {
9499 numButton++;
9500 if (hButton1 == NULL)
9501 {
9502 hButton1 = hh;
9503 }
9504 else
9505 {
9506 hButton2 = hh;
9507 }
9508 }
9509 }
9510
9511 if ((numDirectUIHWND == 1 || numDirectUIHWND == 2) && numButton == 2)
9512 {
9513 if (hButton1 != NULL && hButton2 != NULL)
9514 {
9515 HWND hButton;
9516 HWND hParent;
9517 RECT r1, r2;
9518
9519 GetWindowRect(hButton1, &r1);
9520 GetWindowRect(hButton2, &r2);
9521
9522 hButton = hButton1;
9523
9524 if (numDirectUIHWND == 1)
9525 {
9526 // Warning that there is no signature
9527 if (r1.top < r2.top)
9528 {
9529 hButton = hButton2;
9530 }
9531 }
9532 else
9533 {
9534 // Notification that there is signature
9535 if (r1.left >= r2.left)
9536 {
9537 hButton = hButton2;
9538 }
9539 }
9540
9541 hParent = GetParent(hButton);
9542
9543 // Press the OK button since it was found
9544 if (press)
9545 {
9546 PostMessage(hParent, WM_COMMAND, 1, 0);
9547 }
9548
9549 ret = true;
9550 }
9551 }
9552
9553 FreeWindowList(o);
9554 }
9555 }
9556 }
9557
9558 FreeWindowList(o);
9559 }
9560 }
9561 }
9562 }
9563 }
9564 }
9565 }
9566
9567 if (MsIsVista() == false)
9568 {
9569 ReleaseList(o);
9570 }
9571 else
9572 {
9573 FreeWindowList(o);
9574 }
9575
9576 if (press == false)
9577 {
9578 if (ret)
9579 {
9580 ret = false;
9581
9582 if (nw->StartTick == 0)
9583 {
9584 nw->StartTick = Tick64() + nw->StartTimer;
9585 }
9586 }
9587 }
9588
9589 return ret;
9590 }
9591
9592 // Thread to suppress a warning message
MsNoWarningThreadProc(THREAD * thread,void * param)9593 void MsNoWarningThreadProc(THREAD *thread, void *param)
9594 {
9595 NO_WARNING *nw;
9596 UINT interval;
9597 UINT i;
9598 bool found0 = false;
9599 // Validate arguments
9600 if (thread == NULL)
9601 {
9602 return;
9603 }
9604
9605 nw = (NO_WARNING *)param;
9606
9607 nw->NoWarningThread = thread;
9608 AddRef(thread->ref);
9609
9610 NoticeThreadInit(thread);
9611
9612 interval = 50;
9613
9614 if (MsIsVista())
9615 {
9616 interval = 1000;
9617 }
9618
9619 i = 0;
9620
9621 while (nw->Halt == false)
9622 {
9623 bool found = false;
9624
9625 // Close the alert dialog
9626 found = MsCloseWarningWindow(nw, nw->ThreadId);
9627 if (i == 0)
9628 {
9629 found0 = found;
9630 }
9631 else
9632 {
9633 if (found0 == false && found)
9634 {
9635 break;
9636 }
9637 }
9638 i++;
9639
9640 // Loop until the command incomes from parent thread
9641 Wait(nw->HaltEvent, interval);
9642 }
9643 }
9644
9645 // Initialize the procedure to turn off the warning sound
MsNoWarningSoundInit()9646 char *MsNoWarningSoundInit()
9647 {
9648 char *ret = MsRegReadStr(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "");
9649
9650 if (IsEmptyStr(ret))
9651 {
9652 Free(ret);
9653 ret = NULL;
9654 }
9655 else
9656 {
9657 MsRegWriteStr(REG_CURRENT_USER,
9658 "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",
9659 "", "");
9660 }
9661
9662 return ret;
9663 }
9664
9665 // Release of procedure to turn off the warning sound
MsNoWarningSoundFree(char * s)9666 void MsNoWarningSoundFree(char *s)
9667 {
9668 // Validate arguments
9669 if (s == NULL)
9670 {
9671 return;
9672 }
9673
9674 MsRegWriteStrExpand(REG_CURRENT_USER,
9675 "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",
9676 "", s);
9677
9678 Free(s);
9679 }
9680
9681 // The start of the procedure to suppress the warning
MsInitNoWarning()9682 NO_WARNING *MsInitNoWarning()
9683 {
9684 return MsInitNoWarningEx(0);
9685 }
MsInitNoWarningEx(UINT start_timer)9686 NO_WARNING *MsInitNoWarningEx(UINT start_timer)
9687 {
9688 THREAD *thread;
9689 NO_WARNING *nw = ZeroMalloc(sizeof(NO_WARNING));
9690
9691 nw->StartTimer = (UINT64)start_timer;
9692
9693 // Get the current sound file name
9694 if (MsIsVista() == false)
9695 {
9696 wchar_t *tmp;
9697
9698 // Turn off the unnecessary warning tone in Windows XP or earlier
9699 tmp = MsRegReadStrW(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "");
9700 if (UniIsEmptyStr(tmp) == false)
9701 {
9702 nw->SoundFileName = CopyUniStr(tmp);
9703
9704 MsRegWriteStrW(REG_CURRENT_USER,
9705 "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",
9706 "", L"");
9707 }
9708
9709 Free(tmp);
9710 }
9711
9712 nw->ThreadId = GetCurrentThreadId();
9713 nw->HaltEvent = NewEvent();
9714
9715 thread = NewThread(MsNoWarningThreadProc, nw);
9716 WaitThreadInit(thread);
9717
9718 ReleaseThread(thread);
9719
9720 return nw;
9721 }
9722
9723 // End of the procedure to suppress the warning
MsFreeNoWarning(NO_WARNING * nw)9724 void MsFreeNoWarning(NO_WARNING *nw)
9725 {
9726 // Validate arguments
9727 if (nw == NULL)
9728 {
9729 return;
9730 }
9731
9732 nw->Halt = true;
9733 Set(nw->HaltEvent);
9734
9735 WaitThread(nw->NoWarningThread, INFINITE);
9736 ReleaseThread(nw->NoWarningThread);
9737
9738 ReleaseEvent(nw->HaltEvent);
9739
9740 if (MsIsVista() == false)
9741 {
9742 if (nw->SoundFileName != NULL)
9743 {
9744 MsRegWriteStrExpandW(REG_CURRENT_USER,
9745 "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",
9746 "", nw->SoundFileName);
9747
9748 Free(nw->SoundFileName);
9749 }
9750 }
9751
9752 Free(nw);
9753 }
9754
9755 // Obtain the name of the directory that the inf catalog file is stored
MsGetInfCatalogDir(char * dst,UINT size)9756 void MsGetInfCatalogDir(char *dst, UINT size)
9757 {
9758 // Validate arguments
9759 if (dst == NULL)
9760 {
9761 return;
9762 }
9763
9764 Format(dst, size, "|DriverPackages\\%s\\%s", (MsIsWindows10() ? "Neo6_Win10" : "Neo6_Win8"), (MsIsX64() ? "x64" : "x86"));
9765 }
9766
9767 // Examine whether the virtual LAN card name can be used as a instance name of the VLAN
MsIsValidVLanInstanceNameForInfCatalog(char * instance_name)9768 bool MsIsValidVLanInstanceNameForInfCatalog(char *instance_name)
9769 {
9770 char src_dir[MAX_SIZE];
9771 char tmp[MAX_SIZE];
9772 bool ret;
9773 // Validate arguments
9774 if (instance_name == NULL)
9775 {
9776 return false;
9777 }
9778
9779 MsGetInfCatalogDir(src_dir, sizeof(src_dir));
9780
9781 Format(tmp, sizeof(tmp), "%s\\Neo6_%s_%s.inf", src_dir, (MsIsX64() ? "x64" : "x86"), instance_name);
9782
9783 ret = IsFile(tmp);
9784
9785 return ret;
9786 }
9787
9788 // Delete the device information that is about the device which failed during the installation of the same name before installing the virtual LAN card
MsDeleteTroubleVLAN(char * tag_name,char * instance_name)9789 void MsDeleteTroubleVLAN(char *tag_name, char *instance_name)
9790 {
9791 HDEVINFO dev_info;
9792 SP_DEVINFO_LIST_DETAIL_DATA detail_data;
9793 SP_DEVINFO_DATA data;
9794 UINT i;
9795 char target_name[MAX_SIZE];
9796 LIST *o;
9797 // Validate arguments
9798 if (tag_name == NULL || instance_name == NULL)
9799 {
9800 return;
9801 }
9802
9803 Format(target_name, sizeof(target_name), DRIVER_DEVICE_ID_TAG, instance_name);
9804
9805 // Create a device information list
9806 dev_info = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, NULL);
9807 if (dev_info == NULL)
9808 {
9809 return;
9810 }
9811
9812 Zero(&detail_data, sizeof(detail_data));
9813 detail_data.cbSize = sizeof(detail_data);
9814 if (SetupDiGetDeviceInfoListDetail(dev_info, &detail_data) == false)
9815 {
9816 MsDestroyDevInfo(dev_info);
9817 return;
9818 }
9819
9820 Zero(&data, sizeof(data));
9821 data.cbSize = sizeof(data);
9822
9823 // Enumeration start
9824 o = NewListFast(NULL);
9825
9826 for (i = 0;SetupDiEnumDeviceInfo(dev_info, i, &data);i++)
9827 {
9828 char *buffer;
9829 UINT buffer_size = 8092;
9830 DWORD data_type;
9831
9832 buffer = ZeroMalloc(buffer_size);
9833
9834 if (SetupDiGetDeviceRegistryProperty(dev_info, &data, SPDRP_HARDWAREID, &data_type, (PBYTE)buffer, buffer_size, NULL))
9835 {
9836 if (StrCmpi(buffer, target_name) == 0)
9837 {
9838 // Found
9839 SP_DEVINFO_DATA *data2 = Clone(&data, sizeof(SP_DEVINFO_DATA));
9840
9841 Add(o, data2);
9842 }
9843 }
9844
9845 Free(buffer);
9846 }
9847
9848 for (i = 0;i < LIST_NUM(o);i++)
9849 {
9850 SP_DEVINFO_DATA *data = LIST_DATA(o, i);
9851 bool ret;
9852
9853 ret = SetupDiRemoveDevice(dev_info, data);
9854
9855 Debug("Deleting Troubled NIC %u: %u\n", i, ret);
9856
9857 Free(data);
9858 }
9859
9860 ReleaseList(o);
9861
9862 MsDestroyDevInfo(dev_info);
9863 }
9864
9865 // Install a virtual LAN card
MsInstallVLan(char * tag_name,char * connection_tag_name,char * instance_name,MS_DRIVER_VER * ver)9866 bool MsInstallVLan(char *tag_name, char *connection_tag_name, char *instance_name, MS_DRIVER_VER *ver)
9867 {
9868 bool ret;
9869
9870 Lock(vlan_lock);
9871 {
9872 ret = MsInstallVLanWithoutLock(tag_name, connection_tag_name, instance_name, ver);
9873 }
9874 Unlock(vlan_lock);
9875
9876 return ret;
9877 }
MsInstallVLanWithoutLock(char * tag_name,char * connection_tag_name,char * instance_name,MS_DRIVER_VER * ver)9878 bool MsInstallVLanWithoutLock(char *tag_name, char *connection_tag_name, char *instance_name, MS_DRIVER_VER *ver)
9879 {
9880 wchar_t infpath[MAX_PATH];
9881 char hwid[MAX_PATH];
9882 wchar_t hwid_w[MAX_PATH];
9883 bool ret = false;
9884 char neo_sys[MAX_PATH];
9885 UCHAR new_mac_address[6];
9886 UINT i;
9887 // Validate arguments
9888 if (instance_name == NULL || tag_name == NULL || connection_tag_name == NULL || ver == NULL)
9889 {
9890 return false;
9891 }
9892
9893 if (MsIsNt() == false)
9894 {
9895 // For Windows 9x
9896 return MsInstallVLan9x(instance_name, ver);
9897 }
9898
9899 if (MsIsInfCatalogRequired())
9900 {
9901 if (MsIsValidVLanInstanceNameForInfCatalog(instance_name) == false)
9902 {
9903 Debug("MsIsValidVLanInstanceNameForInfCatalog() returns false.\n");
9904 return false;
9905 }
9906
9907 StrUpper(instance_name);
9908 }
9909
9910 Zero(hwid, sizeof(hwid));
9911 Format(hwid, sizeof(hwid), DRIVER_DEVICE_ID_TAG, instance_name);
9912 StrToUni(hwid_w, sizeof(hwid_w), hwid);
9913
9914 // Examine whether the virtual LAN card with the specified name has already registered
9915 if (MsIsVLanExists(tag_name, instance_name))
9916 {
9917 // Already be registered
9918 Debug("MsIsVLanExists() returns true.\n");
9919 return false;
9920 }
9921
9922 // Determining destination .sys file name of the installation
9923 if (MsIsInfCatalogRequired() == false)
9924 {
9925 if (MsMakeNewNeoDriverFilename(neo_sys, sizeof(neo_sys)) == false)
9926 {
9927 return false;
9928 }
9929 }
9930 else
9931 {
9932 if (MsIsWindows10() == false)
9933 {
9934 Format(neo_sys, sizeof(neo_sys), "Neo_%s.sys", instance_name);
9935 }
9936 else
9937 {
9938 Format(neo_sys, sizeof(neo_sys), "Neo6_%s_%s.sys", (MsIsX64() ? "x64" : "x86"), instance_name);
9939 }
9940 }
9941
9942 // Starting the Installation
9943 if (MsStartDriverInstall(instance_name, NULL, neo_sys, new_mac_address, ver) == false)
9944 {
9945 return false;
9946 }
9947 MsGetDriverPath(instance_name, NULL, NULL, infpath, NULL, NULL, NULL, neo_sys);
9948
9949 // Delete the device information that is left on fail of installation
9950 if (MsIsNt())
9951 {
9952 MsDeleteTroubleVLAN(tag_name, instance_name);
9953 }
9954
9955 // Call the Win32 API
9956 ret = MsInstallVLanInternal(infpath, hwid_w, hwid);
9957
9958 // Installation complete
9959 MsFinishDriverInstall(instance_name, neo_sys);
9960
9961 for (i = 0;i < 5;i++)
9962 {
9963 MsInitNetworkConfig(tag_name, instance_name, connection_tag_name);
9964 if (MsIsInfCatalogRequired())
9965 {
9966 // Write the MAC address
9967 char mac_address_str[MAX_SIZE];
9968 BinToStr(mac_address_str, sizeof(mac_address_str), new_mac_address, sizeof(new_mac_address));
9969 MsSetMacAddress(VLAN_ADAPTER_NAME_TAG, instance_name, mac_address_str);
9970 }
9971
9972 SleepThread(MsIsVista() ? 1000 : 300);
9973 }
9974
9975 if (ret)
9976 {
9977 MsDisableVLan(instance_name);
9978 SleepThread(MsIsVista() ? 1000 : 300);
9979 MsEnableVLan(instance_name);
9980 }
9981
9982 return ret;
9983 }
9984
9985 // Test function
MsTest()9986 void MsTest()
9987 {
9988 }
9989
9990 // Install a virtual LAN card (by calling Win32 API)
MsInstallVLanInternal(wchar_t * infpath,wchar_t * hwid_w,char * hwid)9991 bool MsInstallVLanInternal(wchar_t *infpath, wchar_t *hwid_w, char *hwid)
9992 {
9993 bool need_reboot;
9994 bool ret = false;
9995 wchar_t inf_class_name[MAX_PATH];
9996 GUID inf_class_guid;
9997 HDEVINFO device_info;
9998 SP_DEVINFO_DATA device_info_data;
9999 // Validate arguments
10000 if (infpath == NULL || hwid_w == NULL || hwid == NULL)
10001 {
10002 return false;
10003 }
10004
10005 Debug("MsInstallVLanInternal('%S', '%S', '%s');\n",
10006 infpath, hwid_w, hwid);
10007
10008 Zero(&inf_class_guid, sizeof(inf_class_guid));
10009 Zero(&device_info, sizeof(device_info));
10010 Zero(&device_info_data, sizeof(device_info_data));
10011 Zero(inf_class_name, sizeof(inf_class_name));
10012
10013 // Get the class GUID of the inf file
10014 if (SetupDiGetINFClassW(infpath, &inf_class_guid, inf_class_name, sizeof(inf_class_name), NULL))
10015 {
10016 // Get the device information set
10017 device_info = SetupDiCreateDeviceInfoList(&inf_class_guid, NULL);
10018 if (device_info != INVALID_HANDLE_VALUE)
10019 {
10020 // Windows 2000 or later
10021 Zero(&device_info_data, sizeof(device_info_data));
10022 device_info_data.cbSize = sizeof(device_info_data);
10023 if (SetupDiCreateDeviceInfoW(device_info, inf_class_name, &inf_class_guid,
10024 NULL, NULL, DICD_GENERATE_ID, &device_info_data))
10025 {
10026 char hwid_copy[MAX_SIZE];
10027 Zero(hwid_copy, sizeof(hwid_copy));
10028 StrCpy(hwid_copy, sizeof(hwid_copy), hwid);
10029
10030 // Set the registry information
10031 if (SetupDiSetDeviceRegistryProperty(device_info, &device_info_data,
10032 SPDRP_HARDWAREID, (BYTE *)hwid_copy, sizeof(hwid_copy)))
10033 {
10034 NO_WARNING *nw = NULL;
10035
10036 //if (MsIsVista() == false)
10037 {
10038 nw = MsInitNoWarning();
10039 }
10040
10041 // Start the class installer
10042 if (SetupDiCallClassInstaller(DIF_REGISTERDEVICE, device_info,
10043 &device_info_data))
10044 {
10045 // Do the installation
10046 if (ms->nt->UpdateDriverForPlugAndPlayDevicesW(
10047 NULL, hwid_w, infpath, 1, &need_reboot))
10048 {
10049 ret = true;
10050 }
10051 else
10052 {
10053 // Installation Failed
10054 Debug("UpdateDriverForPlugAndPlayDevicesW Error: %X\n", GetLastError());
10055 if (SetupDiCallClassInstaller(DIF_REMOVE, device_info,
10056 &device_info_data) == false)
10057 {
10058 Debug("SetupDiCallClassInstaller for Delete Failed. Err=%X\n", GetLastError());
10059 }
10060
10061 if (SetupDiRemoveDevice(device_info, &device_info_data) == false)
10062 {
10063 Debug("SetupDiRemoveDevice for Delete Failed. Err=%X\n", GetLastError());
10064 }
10065 }
10066 }
10067 else
10068 {
10069 Debug("SetupDiCallClassInstaller for Create Error: %X\n", GetLastError());
10070 }
10071
10072 MsFreeNoWarning(nw);
10073 }
10074 else
10075 {
10076 Debug("SetupDiSetDeviceRegistryProperty Error: %X\n", GetLastError());
10077 }
10078 }
10079 else
10080 {
10081 Debug("SetupDiCreateDeviceInfoW Error: %X\n", GetLastError());
10082 }
10083 // Remove the device information set
10084 SetupDiDestroyDeviceInfoList(device_info);
10085 }
10086 else
10087 {
10088 Debug("SetupDiCreateDeviceInfoList Error: %X\n", GetLastError());
10089 }
10090 }
10091 else
10092 {
10093 Debug("SetupDiGetINFClassW Error: %X\n", GetLastError());
10094 }
10095
10096 return ret;
10097 }
10098
10099 // Get the device information from the device ID
MsGetDevInfoFromDeviceId(SP_DEVINFO_DATA * dev_info_data,char * device_id)10100 HDEVINFO MsGetDevInfoFromDeviceId(SP_DEVINFO_DATA *dev_info_data, char *device_id)
10101 {
10102 HDEVINFO dev_info;
10103 SP_DEVINFO_LIST_DETAIL_DATA detail_data;
10104 SP_DEVINFO_DATA data;
10105 UINT i;
10106 bool found;
10107 char target_name[MAX_SIZE];
10108 // Validate arguments
10109 if (dev_info_data == NULL || device_id == NULL)
10110 {
10111 return NULL;
10112 }
10113
10114 StrCpy(target_name, sizeof(target_name), device_id);
10115
10116 // Create a device information list
10117 dev_info = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, NULL);
10118 if (dev_info == NULL)
10119 {
10120 return NULL;
10121 }
10122
10123 Zero(&detail_data, sizeof(detail_data));
10124 detail_data.cbSize = sizeof(detail_data);
10125 if (SetupDiGetDeviceInfoListDetail(dev_info, &detail_data) == false)
10126 {
10127 MsDestroyDevInfo(dev_info);
10128 return NULL;
10129 }
10130
10131 Zero(&data, sizeof(data));
10132 data.cbSize = sizeof(data);
10133
10134 // Enumeration start
10135 found = false;
10136 for (i = 0;SetupDiEnumDeviceInfo(dev_info, i, &data);i++)
10137 {
10138 char *buffer;
10139 UINT buffer_size = 8092;
10140 DWORD data_type;
10141
10142 buffer = ZeroMalloc(buffer_size);
10143
10144 if (SetupDiGetDeviceRegistryProperty(dev_info, &data, SPDRP_HARDWAREID, &data_type, (PBYTE)buffer, buffer_size, NULL))
10145 {
10146 if (StrCmpi(buffer, target_name) == 0)
10147 {
10148 // Found
10149 found = true;
10150 }
10151 }
10152
10153 Free(buffer);
10154
10155 if (found)
10156 {
10157 break;
10158 }
10159 }
10160
10161 if (found == false)
10162 {
10163 MsDestroyDevInfo(dev_info);
10164 return NULL;
10165 }
10166 else
10167 {
10168 Copy(dev_info_data, &data, sizeof(data));
10169 return dev_info;
10170 }
10171 }
10172
10173 // Examine whether the specified device is operating
MsIsDeviceRunning(HDEVINFO info,SP_DEVINFO_DATA * dev_info_data)10174 bool MsIsDeviceRunning(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)
10175 {
10176 SP_DEVINFO_LIST_DETAIL_DATA detail;
10177 UINT status = 0, problem = 0;
10178 // Validate arguments
10179 if (info == NULL || dev_info_data == NULL)
10180 {
10181 return false;
10182 }
10183
10184 Zero(&detail, sizeof(detail));
10185 detail.cbSize = sizeof(detail);
10186
10187 if (SetupDiGetDeviceInfoListDetail(info, &detail) == false ||
10188 ms->nt->CM_Get_DevNode_Status_Ex(&status, &problem, dev_info_data->DevInst,
10189 0, detail.RemoteMachineHandle) != CR_SUCCESS)
10190 {
10191 return false;
10192 }
10193
10194 if (status & 8)
10195 {
10196 return true;
10197 }
10198 else
10199 {
10200 return false;
10201 }
10202 }
10203
10204 // Start the specified device
MsStartDevice(HDEVINFO info,SP_DEVINFO_DATA * dev_info_data)10205 bool MsStartDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)
10206 {
10207 SP_PROPCHANGE_PARAMS p;
10208 // Validate arguments
10209 if (info == NULL || dev_info_data == NULL)
10210 {
10211 return false;
10212 }
10213
10214 Zero(&p, sizeof(p));
10215 p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
10216 p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
10217 p.StateChange = DICS_ENABLE;
10218 p.Scope = DICS_FLAG_GLOBAL;
10219 if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)))
10220 {
10221 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data);
10222 }
10223
10224 Zero(&p, sizeof(p));
10225 p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
10226 p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
10227 p.StateChange = DICS_ENABLE;
10228 p.Scope = DICS_FLAG_CONFIGSPECIFIC;
10229
10230 if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false ||
10231 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data) == false)
10232 {
10233 return false;
10234 }
10235
10236 return true;
10237 }
10238
10239 // Stop the specified device
MsStopDevice(HDEVINFO info,SP_DEVINFO_DATA * dev_info_data)10240 bool MsStopDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)
10241 {
10242 SP_PROPCHANGE_PARAMS p;
10243 // Validate arguments
10244 if (info == NULL || dev_info_data == NULL)
10245 {
10246 return false;
10247 }
10248
10249 Zero(&p, sizeof(p));
10250 p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
10251 p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
10252 p.StateChange = DICS_DISABLE;
10253 p.Scope = DICS_FLAG_CONFIGSPECIFIC;
10254
10255 if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false ||
10256 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data) == false)
10257 {
10258 return false;
10259 }
10260
10261 return true;
10262 }
10263
10264 // Remove the specified device
MsDeleteDevice(HDEVINFO info,SP_DEVINFO_DATA * dev_info_data)10265 bool MsDeleteDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)
10266 {
10267 SP_REMOVEDEVICE_PARAMS p;
10268 SP_DEVINFO_LIST_DETAIL_DATA detail;
10269 char device_id[MAX_PATH];
10270 CONFIGRET ret;
10271 // Validate arguments
10272 if (info == NULL || dev_info_data == NULL)
10273 {
10274 return false;
10275 }
10276
10277 Zero(&detail, sizeof(detail));
10278 detail.cbSize = sizeof(detail);
10279
10280 if (SetupDiGetDeviceInfoListDetail(info, &detail) == false)
10281 {
10282 Debug("SetupDiGetDeviceInfoListDetail Failed. Err=0x%X\n", GetLastError());
10283 return false;
10284 }
10285
10286 ret = ms->nt->CM_Get_Device_ID_Ex(dev_info_data->DevInst, device_id, sizeof(device_id),
10287 0, detail.RemoteMachineHandle);
10288 if (ret != CR_SUCCESS)
10289 {
10290 Debug("CM_Get_Device_ID_Ex Failed. Err=0x%X\n", ret);
10291 return false;
10292 }
10293
10294 Zero(&p, sizeof(p));
10295 p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
10296 p.ClassInstallHeader.InstallFunction = DIF_REMOVE;
10297 p.Scope = DI_REMOVEDEVICE_GLOBAL;
10298
10299 if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false)
10300 {
10301 Debug("SetupDiSetClassInstallParams Failed. Err=0x%X\n", GetLastError());
10302 return false;
10303 }
10304
10305 if (SetupDiCallClassInstaller(DIF_REMOVE, info, dev_info_data) == false)
10306 {
10307 Debug("SetupDiCallClassInstaller Failed. Err=0x%X\n", GetLastError());
10308 return false;
10309 }
10310
10311 return true;
10312 }
10313
10314 // Enable the virtual LAN card
MsEnableVLan(char * instance_name)10315 bool MsEnableVLan(char *instance_name)
10316 {
10317 bool ret;
10318
10319 Lock(vlan_lock);
10320 {
10321 ret = MsEnableVLanWithoutLock(instance_name);
10322 }
10323 Unlock(vlan_lock);
10324
10325 return ret;
10326 }
MsEnableVLanWithoutLock(char * instance_name)10327 bool MsEnableVLanWithoutLock(char *instance_name)
10328 {
10329 char tmp[MAX_PATH];
10330 HDEVINFO h;
10331 bool ret;
10332 SP_DEVINFO_DATA data;
10333 // Validate arguments
10334 if (instance_name == NULL)
10335 {
10336 return false;
10337 }
10338
10339 if (MsIsNt() == false)
10340 {
10341 return false;
10342 }
10343
10344 Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);
10345
10346 h = MsGetDevInfoFromDeviceId(&data, tmp);
10347 if (h == NULL)
10348 {
10349 return false;
10350 }
10351
10352 ret = MsStartDevice(h, &data);
10353
10354 MsDestroyDevInfo(h);
10355
10356 return ret;
10357 }
10358
10359 // Disable the virtual LAN card
MsDisableVLan(char * instance_name)10360 bool MsDisableVLan(char *instance_name)
10361 {
10362 bool ret;
10363
10364 Lock(vlan_lock);
10365 {
10366 ret = MsDisableVLanWithoutLock(instance_name);
10367 }
10368 Unlock(vlan_lock);
10369
10370 return ret;
10371 }
MsDisableVLanWithoutLock(char * instance_name)10372 bool MsDisableVLanWithoutLock(char *instance_name)
10373 {
10374 char tmp[MAX_PATH];
10375 HDEVINFO h;
10376 bool ret;
10377 SP_DEVINFO_DATA data;
10378 // Validate arguments
10379 if (instance_name == NULL)
10380 {
10381 return false;
10382 }
10383
10384 if (MsIsNt() == false)
10385 {
10386 return false;
10387 }
10388
10389 Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);
10390
10391 h = MsGetDevInfoFromDeviceId(&data, tmp);
10392 if (h == NULL)
10393 {
10394 return false;
10395 }
10396
10397 ret = MsStopDevice(h, &data);
10398
10399 MsDestroyDevInfo(h);
10400
10401 return ret;
10402 }
10403
10404 // Restart the virtual LAN card
MsRestartVLan(char * instance_name)10405 void MsRestartVLan(char *instance_name)
10406 {
10407 Lock(vlan_lock);
10408 {
10409 MsRestartVLanWithoutLock(instance_name);
10410 }
10411 Unlock(vlan_lock);
10412 }
MsRestartVLanWithoutLock(char * instance_name)10413 void MsRestartVLanWithoutLock(char *instance_name)
10414 {
10415 // Validate arguments
10416 if (instance_name == NULL)
10417 {
10418 return;
10419 }
10420
10421 if (MsIsNt() == false)
10422 {
10423 return;
10424 }
10425
10426 if (MsIsVLanEnabled(instance_name) == false)
10427 {
10428 return;
10429 }
10430
10431 MsDisableVLan(instance_name);
10432 MsEnableVLan(instance_name);
10433 }
10434
10435 // Get whether the virtual LAN card is working
MsIsVLanEnabled(char * instance_name)10436 bool MsIsVLanEnabled(char *instance_name)
10437 {
10438 bool ret;
10439
10440 Lock(vlan_lock);
10441 {
10442 ret = MsIsVLanEnabledWithoutLock(instance_name);
10443 }
10444 Unlock(vlan_lock);
10445
10446 return ret;
10447 }
MsIsVLanEnabledWithoutLock(char * instance_name)10448 bool MsIsVLanEnabledWithoutLock(char *instance_name)
10449 {
10450 char tmp[MAX_PATH];
10451 HDEVINFO h;
10452 bool ret;
10453 SP_DEVINFO_DATA data;
10454 // Validate arguments
10455 if (instance_name == NULL)
10456 {
10457 return false;
10458 }
10459
10460 if (MsIsNt() == false)
10461 {
10462 return true;
10463 }
10464
10465 Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);
10466
10467 h = MsGetDevInfoFromDeviceId(&data, tmp);
10468 if (h == NULL)
10469 {
10470 return false;
10471 }
10472
10473 ret = MsIsDeviceRunning(h, &data);
10474
10475 MsDestroyDevInfo(h);
10476
10477 return ret;
10478 }
10479
10480 // Uninstall the virtual LAN card
MsUninstallVLan(char * instance_name)10481 bool MsUninstallVLan(char *instance_name)
10482 {
10483 bool ret;
10484
10485 Lock(vlan_lock);
10486 {
10487 ret = MsUninstallVLanWithoutLock(instance_name);
10488 }
10489 Unlock(vlan_lock);
10490
10491 return ret;
10492 }
MsUninstallVLanWithoutLock(char * instance_name)10493 bool MsUninstallVLanWithoutLock(char *instance_name)
10494 {
10495 char tmp[MAX_PATH];
10496 HDEVINFO h;
10497 bool ret;
10498 SP_DEVINFO_DATA data;
10499 // Validate arguments
10500 if (instance_name == NULL)
10501 {
10502 return false;
10503 }
10504
10505 Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);
10506
10507 h = MsGetDevInfoFromDeviceId(&data, tmp);
10508 if (h == NULL)
10509 {
10510 return false;
10511 }
10512
10513 ret = MsDeleteDevice(h, &data);
10514
10515 MsDestroyDevInfo(h);
10516
10517 return ret;
10518 }
10519
10520 // Dispose the device information
MsDestroyDevInfo(HDEVINFO info)10521 void MsDestroyDevInfo(HDEVINFO info)
10522 {
10523 // Validate arguments
10524 if (info == NULL)
10525 {
10526 return;
10527 }
10528
10529 SetupDiDestroyDeviceInfoList(info);
10530 }
10531
10532 // Start the driver installation
MsStartDriverInstall(char * instance_name,UCHAR * mac_address,char * neo_sys,UCHAR * ret_mac_address,MS_DRIVER_VER * ver)10533 bool MsStartDriverInstall(char *instance_name, UCHAR *mac_address, char *neo_sys, UCHAR *ret_mac_address, MS_DRIVER_VER *ver)
10534 {
10535 wchar_t src_inf[MAX_PATH];
10536 wchar_t src_sys[MAX_PATH];
10537 wchar_t dest_inf[MAX_PATH];
10538 wchar_t dest_sys[MAX_PATH];
10539 wchar_t src_cat[MAX_PATH];
10540 wchar_t dst_cat[MAX_PATH];
10541 UCHAR mac_address_bin[6];
10542 char mac_address_str[32];
10543 UINT size;
10544 char *tmp;
10545 BUF *b;
10546 IO *io;
10547 char str_year[16];
10548 char str_month[16];
10549 char str_day[16];
10550 char str_major[16];
10551 char str_minor[16];
10552 char str_build[16];
10553 // Validate arguments
10554 if (instance_name == NULL || neo_sys == NULL || ver == NULL)
10555 {
10556 return false;
10557 }
10558
10559 Format(str_year, sizeof(str_year), "%04d", ver->Year);
10560 Format(str_month, sizeof(str_month), "%02d", ver->Month);
10561 Format(str_day, sizeof(str_day), "%02d", ver->Day);
10562
10563 ToStr(str_major, ver->Major);
10564 ToStr(str_minor, ver->Minor);
10565 ToStr(str_build, ver->Build);
10566
10567 MsGetDriverPath(instance_name, src_inf, src_sys, dest_inf, dest_sys, src_cat, dst_cat, neo_sys);
10568 Debug("MsStartDriverInstall\n");
10569 Debug(" instance_name: %s\n", instance_name);
10570 Debug(" src_inf: %S\n", src_inf);
10571 Debug(" src_sys: %S\n", src_sys);
10572 Debug(" dest_inf: %S\n", dest_inf);
10573 Debug(" dest_sys: %S\n", dest_sys);
10574 Debug(" src_cat: %S\n", src_cat);
10575 Debug(" dst_cat: %S\n", dst_cat);
10576 Debug(" neo_sys: %s\n", neo_sys);
10577
10578 // Processing INF file
10579 io = FileOpenW(src_inf, false);
10580 if (io == NULL)
10581 {
10582 return false;
10583 }
10584
10585 size = FileSize(io);
10586 tmp = ZeroMalloc(size * 2);
10587 if (FileRead(io, tmp, size) == false)
10588 {
10589 FileClose(io);
10590 Free(tmp);
10591 return false;
10592 }
10593
10594 FileClose(io);
10595
10596 if (mac_address == NULL)
10597 {
10598 MsGenMacAddress(mac_address_bin);
10599 }
10600 else
10601 {
10602 Copy(mac_address_bin, mac_address, 6);
10603 }
10604
10605 BinToStr(mac_address_str, sizeof(mac_address_str), mac_address_bin, sizeof(mac_address_bin));
10606
10607 //ReplaceStrEx(tmp, size * 2, tmp, "$TAG_DRIVER_VER$", DRIVER_VER_STR, false);
10608 ReplaceStrEx(tmp, size * 2, tmp, "$TAG_INSTANCE_NAME$", instance_name, false);
10609 ReplaceStrEx(tmp, size * 2, tmp, "$TAG_MAC_ADDRESS$", mac_address_str, false);
10610 ReplaceStrEx(tmp, size * 2, tmp, "$TAG_SYS_NAME$", neo_sys, false);
10611 ReplaceStrEx(tmp, size * 2, tmp, "$YEAR$", str_year, false);
10612 ReplaceStrEx(tmp, size * 2, tmp, "$MONTH$", str_month, false);
10613 ReplaceStrEx(tmp, size * 2, tmp, "$DAY$", str_day, false);
10614 ReplaceStrEx(tmp, size * 2, tmp, "$VER_MAJOR$", str_major, false);
10615 ReplaceStrEx(tmp, size * 2, tmp, "$VER_MINOR$", str_minor, false);
10616 ReplaceStrEx(tmp, size * 2, tmp, "$VER_BUILD$", str_build, false);
10617
10618 if (MsIsVista())
10619 {
10620 //ReplaceStrEx(tmp, size * 2, tmp, "\"100\"", "\"2000\"", false);
10621 }
10622
10623 io = FileCreateW(dest_inf);
10624 if (io == NULL)
10625 {
10626 Free(tmp);
10627 return false;
10628 }
10629
10630 FileWrite(io, tmp, StrLen(tmp));
10631 FileClose(io);
10632
10633 Free(tmp);
10634
10635 // Processing the SYS file
10636 b = ReadDumpW(src_sys);
10637 if (b == NULL)
10638 {
10639 return false;
10640 }
10641
10642 if (DumpBufW(b, dest_sys) == false)
10643 {
10644 FreeBuf(b);
10645 return false;
10646 }
10647
10648 FreeBuf(b);
10649
10650 // Copy of the catalog file
10651 if (IsEmptyUniStr(src_cat) == false && IsEmptyUniStr(dst_cat) == false)
10652 {
10653 if (FileCopyW(src_cat, dst_cat) == false)
10654 {
10655 return false;
10656 }
10657 }
10658
10659 if (ret_mac_address != NULL)
10660 {
10661 Copy(ret_mac_address, mac_address_bin, 6);
10662 }
10663
10664 return true;
10665 }
10666
10667 // Generation of the MAC address
MsGenMacAddress(UCHAR * mac)10668 void MsGenMacAddress(UCHAR *mac)
10669 {
10670 UCHAR hash_src[40];
10671 UCHAR hash[20];
10672 UINT64 now;
10673 // Validate arguments
10674 if (mac == NULL)
10675 {
10676 return;
10677 }
10678
10679 Rand(hash_src, 40);
10680 now = SystemTime64();
10681 Copy(hash_src, &now, sizeof(now));
10682
10683 Hash(hash, hash_src, sizeof(hash_src), true);
10684
10685 mac[0] = 0x5E;
10686 mac[1] = hash[0];
10687 mac[2] = hash[1];
10688 mac[3] = hash[2];
10689 mac[4] = hash[3];
10690 mac[5] = hash[4];
10691 }
10692
10693 // Finish the driver installation
MsFinishDriverInstall(char * instance_name,char * neo_sys)10694 void MsFinishDriverInstall(char *instance_name, char *neo_sys)
10695 {
10696 wchar_t src_inf[MAX_PATH];
10697 wchar_t src_sys[MAX_PATH];
10698 wchar_t dest_inf[MAX_PATH];
10699 wchar_t dest_sys[MAX_PATH];
10700 wchar_t src_cat[MAX_SIZE];
10701 wchar_t dst_cat[MAX_SIZE];
10702 // Validate arguments
10703 if (instance_name == NULL)
10704 {
10705 return;
10706 }
10707
10708 MsGetDriverPath(instance_name, src_inf, src_sys, dest_inf, dest_sys, src_cat, dst_cat, neo_sys);
10709
10710 // Delete the files
10711 FileDeleteW(dest_inf);
10712 FileDeleteW(dest_sys);
10713
10714 if (IsEmptyUniStr(dst_cat) == false)
10715 {
10716 FileDeleteW(dst_cat);
10717 }
10718 }
10719
10720 // Get the path to the driver file
MsGetDriverPath(char * instance_name,wchar_t * src_inf,wchar_t * src_sys,wchar_t * dest_inf,wchar_t * dest_sys,wchar_t * src_cat,wchar_t * dest_cat,char * neo_sys)10721 void MsGetDriverPath(char *instance_name, wchar_t *src_inf, wchar_t *src_sys, wchar_t *dest_inf, wchar_t *dest_sys, wchar_t *src_cat, wchar_t *dest_cat, char *neo_sys)
10722 {
10723 wchar_t *src_filename;
10724 wchar_t *src_sys_filename;
10725 // Validate arguments
10726 if (instance_name == NULL)
10727 {
10728 return;
10729 }
10730
10731 // WinNT x86
10732 src_filename = L"|DriverPackages\\Neo\\x86\\Neo_x86.inf";
10733 src_sys_filename = L"|DriverPackages\\Neo\\x86\\Neo_x86.sys";
10734
10735 if (MsIsNt() == false)
10736 {
10737 // Win9x
10738 src_filename = L"|DriverPackages\\Neo9x\\x86\\Neo9x_x86.inf";
10739 src_sys_filename = L"|DriverPackages\\Neo9x\\x86\\Neo9x_x86.sys";
10740 }
10741 else if (MsIsX64())
10742 {
10743 // WinNT x64
10744 src_filename = L"|DriverPackages\\Neo\\x64\\Neo_x64.inf";
10745 src_sys_filename = L"|DriverPackages\\Neo\\x64\\Neo_x64.sys";
10746 }
10747
10748 if (MsIsWindows7())
10749 {
10750 // Use the NDIS 6.2 driver for Windows 7 or later
10751 if (MsIsX64())
10752 {
10753 src_filename = L"|DriverPackages\\Neo6\\x64\\Neo6_x64.inf";
10754 src_sys_filename = L"|DriverPackages\\Neo6\\x64\\Neo6_x64.sys";
10755 }
10756 else
10757 {
10758 src_filename = L"|DriverPackages\\Neo6\\x86\\Neo6_x86.inf";
10759 src_sys_filename = L"|DriverPackages\\Neo6\\x86\\Neo6_x86.sys";
10760 }
10761 }
10762
10763 if (MsIsInfCatalogRequired())
10764 {
10765 // Windows 8 or later
10766 if (MsIsX64())
10767 {
10768 src_filename = L"|DriverPackages\\Neo6_Win8\\x64\\Neo6_x64.inf";
10769 src_sys_filename = L"|DriverPackages\\Neo6_Win8\\x64\\Neo6_x64.sys";
10770 }
10771 else
10772 {
10773 src_filename = L"|DriverPackages\\Neo6_Win8\\x86\\Neo6_x86.inf";
10774 src_sys_filename = L"|DriverPackages\\Neo6_Win8\\x86\\Neo6_x86.sys";
10775 }
10776 }
10777
10778 if (src_inf != NULL)
10779 {
10780 if (MsIsInfCatalogRequired() == false)
10781 {
10782 // Windows 7 or before
10783 UniStrCpy(src_inf, MAX_PATH, src_filename);
10784 }
10785 else
10786 {
10787 // Windows 8.1 or later
10788 char tmp[MAX_SIZE];
10789
10790 MsGetInfCatalogDir(tmp, sizeof(tmp));
10791
10792 UniFormat(src_inf, MAX_PATH, L"%S\\Neo6_%S_%S.inf", tmp, (MsIsX64() ? "x64" : "x86"), instance_name);
10793 }
10794 }
10795
10796 if (src_sys != NULL)
10797 {
10798 UniStrCpy(src_sys, MAX_PATH, src_sys_filename);
10799
10800 if (MsIsWindows10())
10801 {
10802 UniFormat(src_sys, MAX_PATH, L"|DriverPackages\\Neo6_Win10\\%S\\Neo6_%S_%S.sys",
10803 (MsIsX64() ? "x64" : "x86"), (MsIsX64() ? "x64" : "x86"), instance_name);
10804 }
10805 }
10806
10807 if (dest_inf != NULL)
10808 {
10809 char inf_name[MAX_PATH];
10810
10811 if (MsIsInfCatalogRequired() == false)
10812 {
10813 Format(inf_name, sizeof(inf_name), "Neo_%s.inf", instance_name);
10814 }
10815 else
10816 {
10817 Format(inf_name, sizeof(inf_name), "Neo6_%s_%s.inf", (MsIsX64() ? "x64" : "x86"), instance_name);
10818 }
10819 UniFormat(dest_inf, MAX_PATH, L"%s\\%S", ms->MyTempDirW, inf_name);
10820 }
10821
10822 if (dest_sys != NULL)
10823 {
10824 char sys_name[MAX_PATH];
10825 StrCpy(sys_name, sizeof(sys_name), neo_sys);
10826 UniFormat(dest_sys, MAX_PATH, L"%s\\%S", ms->MyTempDirW, sys_name);
10827 }
10828
10829 if (src_cat != NULL)
10830 {
10831 if (MsIsInfCatalogRequired())
10832 {
10833 char tmp[MAX_SIZE];
10834
10835 MsGetInfCatalogDir(tmp, sizeof(tmp));
10836
10837 if (MsIsWindows8() == false)
10838 {
10839 // Windows Vista and Windows 7 uses SHA-1 catalog files
10840 // (Unused? Never reach here!)
10841 UniFormat(src_cat, MAX_PATH, L"%S\\inf.cat", tmp);
10842 }
10843 else
10844 {
10845 // Windows 8 or above uses SHA-256 catalog files
10846 UniFormat(src_cat, MAX_PATH, L"%S\\inf2.cat", tmp);
10847 }
10848
10849 if (MsIsWindows10())
10850 {
10851 // Windows 10
10852 UniFormat(src_cat, MAX_PATH, L"%S\\Neo6_%S_%S.cat", tmp, (MsIsX64() ? "x64" : "x86"), instance_name);
10853 }
10854 }
10855 else
10856 {
10857 UniStrCpy(src_cat, MAX_PATH, L"");
10858 }
10859 }
10860
10861 if (dest_cat != NULL)
10862 {
10863 if (MsIsInfCatalogRequired())
10864 {
10865 if (MsIsWindows10() == false)
10866 {
10867 UniFormat(dest_cat, MAX_PATH, L"%s\\inf_%S.cat", ms->MyTempDirW, instance_name);
10868 }
10869 else
10870 {
10871 UniFormat(dest_cat, MAX_PATH, L"%s\\Neo6_%S_%S.cat", ms->MyTempDirW, (MsIsX64() ? "x64" : "x86"), instance_name);
10872 }
10873 }
10874 else
10875 {
10876 UniStrCpy(dest_cat, MAX_PATH, L"");
10877 }
10878 }
10879 }
MsGetDriverPathA(char * instance_name,char * src_inf,char * src_sys,char * dest_inf,char * dest_sys,char * src_cat,char * dst_cat,char * neo_sys)10880 void MsGetDriverPathA(char *instance_name, char *src_inf, char *src_sys, char *dest_inf, char *dest_sys, char *src_cat, char *dst_cat, char *neo_sys)
10881 {
10882 wchar_t src_inf_w[MAX_PATH];
10883 wchar_t src_sys_w[MAX_PATH];
10884 wchar_t dest_inf_w[MAX_PATH];
10885 wchar_t dest_sys_w[MAX_PATH];
10886 wchar_t src_cat_w[MAX_PATH];
10887 wchar_t dst_cat_w[MAX_PATH];
10888
10889 // Validate arguments
10890 if (instance_name == NULL)
10891 {
10892 return;
10893 }
10894
10895 MsGetDriverPath(instance_name, src_inf_w, src_sys_w, dest_inf_w, dest_sys_w, src_cat_w, dst_cat_w, neo_sys);
10896
10897 UniToStr(src_inf, MAX_PATH, src_inf_w);
10898 UniToStr(src_sys, MAX_PATH, src_sys_w);
10899 UniToStr(dest_inf, MAX_PATH, dest_inf_w);
10900 UniToStr(dest_sys, MAX_PATH, dest_sys_w);
10901 UniToStr(src_cat, MAX_PATH, src_cat_w);
10902 UniToStr(dst_cat, MAX_PATH, dst_cat_w);
10903 }
10904
10905 // Examine whether the virtual LAN card with the specified name has already registered
MsIsVLanExists(char * tag_name,char * instance_name)10906 bool MsIsVLanExists(char *tag_name, char *instance_name)
10907 {
10908 char *guid;
10909 // Validate arguments
10910 if (instance_name == NULL || tag_name == NULL)
10911 {
10912 return false;
10913 }
10914
10915 guid = MsGetNetworkAdapterGuid(tag_name, instance_name);
10916 if (guid == NULL)
10917 {
10918 return false;
10919 }
10920
10921 Free(guid);
10922 return true;
10923 }
10924
10925 // Create a temporary file based on the extension
MsCreateTempFileByExt(char * ext)10926 IO *MsCreateTempFileByExt(char *ext)
10927 {
10928 char *tmp = MsCreateTempFileNameByExt(ext);
10929 IO *ret;
10930
10931 if (tmp == NULL)
10932 {
10933 return NULL;
10934 }
10935
10936 ret = FileCreate(tmp);
10937 Free(tmp);
10938
10939 return ret;
10940 }
10941
10942 // Create a temporary file with the specified extension
MsCreateTempFileNameByExt(char * ext)10943 char *MsCreateTempFileNameByExt(char *ext)
10944 {
10945 UCHAR rand[2];
10946 char *ret = NULL;
10947 // Validate arguments
10948 if (ext == NULL)
10949 {
10950 ext = "tmp";
10951 }
10952 if (ext[0] == '.')
10953 {
10954 ext++;
10955 }
10956 if (StrLen(ext) == 0)
10957 {
10958 ext = "tmp";
10959 }
10960
10961 while (true)
10962 {
10963 char new_filename[MAX_PATH];
10964 char *fullpath;
10965 char rand_str[MAX_PATH];
10966 IO *io;
10967 Rand(rand, sizeof(rand));
10968
10969 BinToStr(rand_str, sizeof(rand_str), rand, sizeof(rand));
10970 Format(new_filename, sizeof(new_filename), "__%s.%s", rand_str, ext);
10971
10972 fullpath = MsCreateTempFileName(new_filename);
10973 io = FileOpen(fullpath, false);
10974 if (io == NULL)
10975 {
10976 ret = fullpath;
10977 break;
10978 }
10979 FileClose(io);
10980
10981 Free(fullpath);
10982 }
10983
10984 return ret;
10985 }
10986
10987 // Create a temporary file
MsCreateTempFile(char * name)10988 IO *MsCreateTempFile(char *name)
10989 {
10990 IO *ret;
10991 char *tmp;
10992 // Validate arguments
10993 if (name == NULL)
10994 {
10995 return NULL;
10996 }
10997
10998 tmp = MsCreateTempFileName(name);
10999 if (tmp == NULL)
11000 {
11001 return NULL;
11002 }
11003
11004 ret = FileCreate(tmp);
11005 Free(tmp);
11006
11007 return ret;
11008 }
11009
11010 // Create a temporary file name
MsCreateTempFileName(char * name)11011 char *MsCreateTempFileName(char *name)
11012 {
11013 char tmp[MAX_PATH];
11014 // Validate arguments
11015 if (name == NULL)
11016 {
11017 return NULL;
11018 }
11019
11020 Format(tmp, sizeof(tmp), "%s\\%s", ms->MyTempDir, name);
11021
11022 return CopyStr(tmp);
11023 }
11024
11025 // Delete VPN temporary directories that remain in the system but not used
MsDeleteTempDir()11026 void MsDeleteTempDir()
11027 {
11028 HANDLE h;
11029 wchar_t dir_mask[MAX_PATH];
11030 WIN32_FIND_DATAA data_a;
11031 WIN32_FIND_DATAW data_w;
11032
11033 Zero(&data_a, sizeof(data_a));
11034 Zero(&data_w, sizeof(data_w));
11035
11036 UniFormat(dir_mask, sizeof(dir_mask), L"%s\\*", ms->TempDirW);
11037
11038 if (IsNt())
11039 {
11040 h = FindFirstFileW(dir_mask, &data_w);
11041 }
11042 else
11043 {
11044 char *tmp_a = CopyUniToStr(dir_mask);
11045
11046 h = FindFirstFileA(tmp_a, &data_a);
11047
11048 Free(tmp_a);
11049 }
11050
11051 if (h != INVALID_HANDLE_VALUE)
11052 {
11053 bool b = true;
11054
11055 do
11056 {
11057 if (IsNt() == false)
11058 {
11059 Zero(&data_w, sizeof(data_w));
11060 StrToUni(data_w.cFileName, sizeof(data_w.cFileName), data_a.cFileName);
11061 data_w.dwFileAttributes = data_a.dwFileAttributes;
11062 data_w.ftCreationTime = data_a.ftCreationTime;
11063 data_w.ftLastWriteTime = data_a.ftLastWriteTime;
11064 data_w.nFileSizeHigh = data_a.nFileSizeHigh;
11065 data_w.nFileSizeLow = data_a.nFileSizeLow;
11066 }
11067
11068 if (UniStrCmpi(data_w.cFileName, L".") != 0 &&
11069 UniStrCmpi(data_w.cFileName, L"..") != 0)
11070 {
11071 if (data_w.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
11072 {
11073 if (UniStartWith(data_w.cFileName, L"VPN_") && UniStrLen(data_w.cFileName) == 8)
11074 {
11075 wchar_t lock_file_name[MAX_PATH];
11076 wchar_t dir_name[MAX_PATH];
11077 bool delete_now = false;
11078 IO *io;
11079
11080 UniFormat(dir_name, sizeof(dir_name), L"%s\\%s",
11081 ms->TempDirW, data_w.cFileName);
11082 MsGenLockFile(lock_file_name, sizeof(lock_file_name), dir_name);
11083
11084 io = FileOpenExW(lock_file_name, false, false);
11085 if (io != NULL)
11086 {
11087 // Mark to delete if the lock file is not locked
11088 FileClose(io);
11089 io = FileOpenW(lock_file_name, true);
11090 if (io != NULL)
11091 {
11092 delete_now = true;
11093 FileClose(io);
11094 }
11095 }
11096 else
11097 {
11098 DIRLIST *d;
11099
11100 // Mark to delete if all files in this folder are not locked
11101 delete_now = true;
11102
11103 d = EnumDirW(dir_name);
11104 if (d != NULL)
11105 {
11106 UINT i;
11107
11108 for (i = 0;i < d->NumFiles;i++)
11109 {
11110 wchar_t full_path[MAX_PATH];
11111
11112 UniFormat(full_path, sizeof(full_path), L"%s\\%s", dir_name, d->File[i]->FileNameW);
11113
11114 io = FileOpenW(full_path, true);
11115 if (io != NULL)
11116 {
11117 delete_now = true;
11118 FileClose(io);
11119 }
11120 }
11121 FreeDir(d);
11122 }
11123 }
11124 if (delete_now)
11125 {
11126 MsDeleteAllFileW(dir_name);
11127
11128 Win32DeleteDirW(dir_name);
11129 }
11130 }
11131 }
11132 }
11133
11134
11135 Zero(&data_w, sizeof(data_w));
11136 Zero(&data_a, sizeof(data_a));
11137
11138 if (IsNt())
11139 {
11140 b = FindNextFileW(h, &data_w);
11141 }
11142 else
11143 {
11144 b = FindNextFileA(h, &data_a);
11145 }
11146 }
11147 while (b);
11148
11149 FindClose(h);
11150 }
11151 }
11152
11153 // Delete all the files in the specified directory
MsDeleteAllFile(char * dir)11154 void MsDeleteAllFile(char *dir)
11155 {
11156 HANDLE h;
11157 char file_mask[MAX_PATH];
11158 WIN32_FIND_DATA data;
11159 // Validate arguments
11160 if (dir == NULL || IsEmptyStr(dir))
11161 {
11162 return;
11163 }
11164
11165 Format(file_mask, sizeof(file_mask), "%s\\*.*", dir);
11166
11167 h = FindFirstFile(file_mask, &data);
11168 if (h != INVALID_HANDLE_VALUE)
11169 {
11170 do
11171 {
11172 if (StrCmpi(data.cFileName, ".") != 0 &&
11173 StrCmpi(data.cFileName, "..") != 0)
11174 {
11175 char fullpath[MAX_PATH];
11176 Format(fullpath, sizeof(fullpath), "%s\\%s", dir, data.cFileName);
11177 if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == false)
11178 {
11179 DeleteFile(fullpath);
11180 }
11181 else
11182 {
11183 MsDeleteAllFile(fullpath);
11184 RemoveDirectory(fullpath);
11185 }
11186 }
11187 }
11188 while (FindNextFile(h, &data));
11189
11190 FindClose(h);
11191 }
11192 }
MsDeleteAllFileW(wchar_t * dir)11193 void MsDeleteAllFileW(wchar_t *dir)
11194 {
11195 HANDLE h;
11196 wchar_t file_mask[MAX_PATH];
11197 WIN32_FIND_DATAW data;
11198 // Validate arguments
11199 if (dir == NULL || UniIsEmptyStr(dir))
11200 {
11201 return;
11202 }
11203
11204 if (IsNt() == false)
11205 {
11206 char *dir_a = CopyUniToStr(dir);
11207
11208 MsDeleteAllFile(dir_a);
11209
11210 Free(dir_a);
11211
11212 return;
11213 }
11214
11215 UniFormat(file_mask, sizeof(file_mask), L"%s\\*.*", dir);
11216
11217 h = FindFirstFileW(file_mask, &data);
11218 if (h != INVALID_HANDLE_VALUE)
11219 {
11220 do
11221 {
11222 if (UniStrCmpi(data.cFileName, L".") != 0 &&
11223 UniStrCmpi(data.cFileName, L"..") != 0)
11224 {
11225 wchar_t fullpath[MAX_PATH];
11226
11227 UniFormat(fullpath, sizeof(fullpath), L"%s\\%s", dir, data.cFileName);
11228
11229 if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == false)
11230 {
11231 DeleteFileW(fullpath);
11232 }
11233 else
11234 {
11235 MsDeleteAllFileW(fullpath);
11236 RemoveDirectoryW(fullpath);
11237 }
11238 }
11239 }
11240 while (FindNextFileW(h, &data));
11241
11242 FindClose(h);
11243 }
11244 }
11245
11246 // Initialize the temporary directory
MsInitTempDir()11247 void MsInitTempDir()
11248 {
11249 wchar_t tmp[MAX_PATH];
11250 wchar_t tmp2[16];
11251 UCHAR random[2];
11252 wchar_t lockfilename[MAX_PATH];
11253 UINT num = 0;
11254
11255 // Delete the unused temporary directory
11256 MsDeleteTempDir();
11257
11258 // Determine the name of the temporary directory
11259 while (true)
11260 {
11261 random[0] = rand() % 256;
11262 random[1] = rand() % 256;
11263 BinToStrW(tmp2, sizeof(tmp2), random, sizeof(random));
11264
11265 UniFormat(tmp, sizeof(tmp), L"%s\\VPN_%s", ms->TempDirW, tmp2);
11266
11267 // Create Directory
11268 if (MakeDirW(tmp))
11269 {
11270 break;
11271 }
11272
11273 if ((num++) >= 100)
11274 {
11275 // Failed many times
11276 char msg[MAX_SIZE];
11277 Format(msg, sizeof(msg),
11278 "Couldn't create Temporary Directory: %s\r\n\r\n"
11279 "Please contact your system administrator.",
11280 tmp);
11281 exit(0);
11282 }
11283 }
11284
11285 ms->MyTempDirW = CopyUniStr(tmp);
11286 ms->MyTempDir = CopyUniToStr(tmp);
11287
11288 // Create a lock file
11289 MsGenLockFile(lockfilename, sizeof(lockfilename), ms->MyTempDirW);
11290 ms->LockFile = FileCreateW(lockfilename);
11291 }
11292
11293 // Release the temporary directory
MsFreeTempDir()11294 void MsFreeTempDir()
11295 {
11296 wchar_t lock_file_name[MAX_SIZE];
11297
11298 // Delete the lock file
11299 MsGenLockFile(lock_file_name, sizeof(lock_file_name), ms->MyTempDirW);
11300 FileClose(ms->LockFile);
11301
11302 // Memory release
11303 Free(ms->MyTempDir);
11304 Free(ms->MyTempDirW);
11305 ms->MyTempDir = NULL;
11306 ms->MyTempDirW = NULL;
11307
11308 // Delete directory
11309 MsDeleteTempDir();
11310 }
11311
11312 // Generation of the name of the lock file
MsGenLockFile(wchar_t * name,UINT size,wchar_t * temp_dir)11313 void MsGenLockFile(wchar_t *name, UINT size, wchar_t *temp_dir)
11314 {
11315 // Validate arguments
11316 if (name == NULL || temp_dir == NULL)
11317 {
11318 return;
11319 }
11320
11321 UniFormat(name, size, L"%s\\VPN_Lock.dat", temp_dir);
11322 }
11323
11324 // Normalization of the configuration of the interface metric of the default gateway in the network configuration
MsNormalizeInterfaceDefaultGatewaySettings(char * tag_name,char * instance_name)11325 void MsNormalizeInterfaceDefaultGatewaySettings(char *tag_name, char *instance_name)
11326 {
11327 char tmp[MAX_SIZE];
11328 char netsh[MAX_PATH];
11329 char *config_str;
11330 char tmp2[MAX_SIZE];
11331 UINT if_index;
11332 UINT if_metric;
11333 // Validate arguments
11334 if (tag_name == NULL || instance_name == NULL)
11335 {
11336 return;
11337 }
11338
11339 Debug("MsNormalizeInterfaceDefaultGatewaySettings()\n");
11340
11341 if (MsIsVista() == false)
11342 {
11343 Debug("MsIsVista() == false\n");
11344 return;
11345 }
11346
11347 Format(tmp2, sizeof(tmp2), tag_name, instance_name);
11348 if_index = Win32GetVLanInterfaceID(tmp2);
11349 Debug("if_index=%u\n", if_index);
11350
11351 if (if_index == 0)
11352 {
11353 return;
11354 }
11355
11356 CombinePath(netsh, sizeof(netsh), MsGetSystem32Dir(), "netsh.exe");
11357
11358 // Set the interface metric value
11359 config_str = MsGetNetworkAdapterGuid(tag_name, instance_name);
11360 if (config_str != NULL)
11361 {
11362 LIST *o;
11363 LIST *o2;
11364
11365 Debug("MsNormalizeInterfaceDefaultGatewaySettings()\n");
11366 Debug("if_index(%s) = %u\n", instance_name, if_index);
11367
11368 Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",
11369 config_str);
11370
11371 o = MsRegReadStrList(REG_LOCAL_MACHINE, tmp, "DefaultGateway");
11372 o2 = MsRegReadStrList(REG_LOCAL_MACHINE, tmp, "DefaultGatewayMetric");
11373
11374 if_metric = MsRegReadInt(REG_LOCAL_MACHINE, tmp, "InterfaceMetric");
11375 Debug("if_metric = %u\n", if_metric);
11376
11377 if (if_metric != 0)
11378 {
11379 if (o != NULL)
11380 {
11381 UINT i;
11382
11383 for (i = 0;i < LIST_NUM(o);i++)
11384 {
11385 char *s = LIST_DATA(o, i);
11386 char tmp[MAX_SIZE];
11387
11388 char *cm = NULL;
11389 UINT current_metric;
11390
11391 if (o2 != NULL)
11392 {
11393 if (LIST_NUM(o2) > i)
11394 {
11395 current_metric = ToInt(LIST_DATA(o2, i));
11396 }
11397 }
11398
11399 Debug("gateway[%u] = %s\n", i, s);
11400 Debug("current_metric[%u] = %u\n", i, current_metric);
11401
11402 if (current_metric == 0)
11403 {
11404 if (IsEmptyStr(s) == false)
11405 {
11406 Format(tmp, sizeof(tmp), "int ipv4 delete route prefix=0.0.0.0/0 interface=%u nexthop=%s",
11407 if_index, s);
11408 Debug("netsh %s\n", tmp);
11409 Run(netsh, tmp, true, true);
11410
11411 Format(tmp, sizeof(tmp), "int ipv4 add route prefix=0.0.0.0/0 interface=%u nexthop=%s metric=%u",
11412 if_index, s, if_metric);
11413 Debug("netsh %s\n", tmp);
11414 Run(netsh, tmp, true, true);
11415 }
11416 }
11417 }
11418 }
11419 }
11420
11421 FreeStrList(o);
11422 FreeStrList(o2);
11423
11424 Free(config_str);
11425 }
11426 }
11427
11428 // Initialization of the network configuration
MsInitNetworkConfig(char * tag_name,char * instance_name,char * connection_tag_name)11429 void MsInitNetworkConfig(char *tag_name, char *instance_name, char *connection_tag_name)
11430 {
11431 char tmp[MAX_SIZE];
11432 char *config_str;
11433 // Validate arguments
11434 if (tag_name == NULL || instance_name == NULL || connection_tag_name == NULL)
11435 {
11436 return;
11437 }
11438
11439 if (MsIsNt() == false)
11440 {
11441 return;
11442 }
11443
11444 // Settings such as string
11445 Format(tmp, sizeof(tmp), connection_tag_name, instance_name);
11446 MsSetNetworkConfig(tag_name, instance_name, tmp, true);
11447
11448 // Set the interface metric value
11449 config_str = MsGetNetworkAdapterGuid(tag_name, instance_name);
11450 if (config_str != NULL)
11451 {
11452 Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",
11453 config_str);
11454
11455 MsRegWriteInt(REG_LOCAL_MACHINE, tmp, "InterfaceMetric", 1);
11456 MsRegWriteInt(REG_LOCAL_MACHINE, tmp, "EnableDeadGWDetect", 0);
11457
11458 if (MsRegReadInt(REG_LOCAL_MACHINE,
11459 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
11460 "packetix_no_optimize") == 0)
11461 {
11462 MsRegWriteInt(REG_LOCAL_MACHINE,
11463 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
11464 "EnableDeadGWDetect",
11465 0);
11466 }
11467
11468 Free(config_str);
11469 }
11470 }
11471
11472 // Configure the network settings
MsSetNetworkConfig(char * tag_name,char * instance_name,char * friendly_name,bool show_icon)11473 void MsSetNetworkConfig(char *tag_name, char *instance_name, char *friendly_name, bool show_icon)
11474 {
11475 char *key;
11476 char *old_name;
11477 // Validate arguments
11478 if (tag_name == NULL || instance_name == NULL || friendly_name == NULL)
11479 {
11480 return;
11481 }
11482
11483 key = MsGetNetworkConfigRegKeyNameFromInstanceName(tag_name, instance_name);
11484 if (key == NULL)
11485 {
11486 return;
11487 }
11488
11489 old_name = MsRegReadStr(REG_LOCAL_MACHINE, key, "Name");
11490 if (old_name != NULL)
11491 {
11492 if (MsIsVista())
11493 {
11494 char arg[MAX_PATH];
11495 char netsh[MAX_PATH];
11496
11497 Format(netsh, sizeof(netsh), "%s\\netsh.exe", MsGetSystem32Dir());
11498
11499 if (StrCmp(old_name, friendly_name) != 0)
11500 {
11501 Format(arg, sizeof(arg), "interface set interface name=\"%s\" newname=\"%s\"",
11502 old_name, friendly_name);
11503
11504 Run(netsh, arg, true, true);
11505 }
11506
11507 Format(arg, sizeof(arg), "netsh interface ipv4 set interface interface=\"%s\" metric=1",
11508 friendly_name);
11509
11510 Run(netsh, arg, true, true);
11511 }
11512 }
11513
11514 if (StrCmp(old_name, friendly_name) != 0)
11515 {
11516 MsRegWriteStr(REG_LOCAL_MACHINE, key, "Name", friendly_name);
11517 }
11518
11519 MsRegWriteInt(REG_LOCAL_MACHINE, key, "ShowIcon", show_icon ? 1 : 0);
11520
11521 Free(key);
11522
11523 Free(old_name);
11524 }
11525
11526 // Get the network configuration key name by the instance name
MsGetNetworkConfigRegKeyNameFromInstanceName(char * tag_name,char * instance_name)11527 char *MsGetNetworkConfigRegKeyNameFromInstanceName(char *tag_name, char *instance_name)
11528 {
11529 char *guid, *ret;
11530 // Validate arguments
11531 if (tag_name == NULL || instance_name == NULL)
11532 {
11533 return NULL;
11534 }
11535
11536 guid = MsGetNetworkAdapterGuid(tag_name, instance_name);
11537 if (guid == NULL)
11538 {
11539 return NULL;
11540 }
11541
11542 ret = MsGetNetworkConfigRegKeyNameFromGuid(guid);
11543
11544 Free(guid);
11545
11546 return ret;
11547 }
11548
11549 // Get the network configuration key name by the GUID
MsGetNetworkConfigRegKeyNameFromGuid(char * guid)11550 char *MsGetNetworkConfigRegKeyNameFromGuid(char *guid)
11551 {
11552 char tmp[MAX_SIZE];
11553 // Validate arguments
11554 if (guid == NULL)
11555 {
11556 return NULL;
11557 }
11558
11559 Format(tmp, sizeof(tmp),
11560 "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",
11561 guid);
11562
11563 return CopyStr(tmp);
11564 }
11565
11566 // Configuring the MAC address
MsSetMacAddress(char * tag_name,char * instance_name,char * mac_address)11567 void MsSetMacAddress(char *tag_name, char *instance_name, char *mac_address)
11568 {
11569 TOKEN_LIST *key_list;
11570 UINT i;
11571 char dest_name[MAX_SIZE];
11572 char mac_str[MAX_SIZE];
11573 // Validate arguments
11574 if (tag_name == NULL || instance_name == NULL)
11575 {
11576 return;
11577 }
11578
11579 // Normalization of the MAC address
11580 if (NormalizeMacAddress(mac_str, sizeof(mac_str), mac_address) == false)
11581 {
11582 return;
11583 }
11584
11585 // Generate the desired name
11586 Format(dest_name, sizeof(dest_name), tag_name, instance_name);
11587
11588 // Enumerate the key
11589 if (MsIsNt())
11590 {
11591 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11592 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
11593 }
11594 else
11595 {
11596 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11597 "System\\CurrentControlSet\\Services\\Class\\Net");
11598 }
11599 if (key_list == NULL)
11600 {
11601 return;
11602 }
11603
11604 for (i = 0;i < key_list->NumTokens;i++)
11605 {
11606 char *key_name = key_list->Token[i];
11607 char full_key_name[MAX_SIZE];
11608 char *driver_desc;
11609
11610 if (MsIsNt())
11611 {
11612 Format(full_key_name, sizeof(full_key_name),
11613 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
11614 key_name);
11615 }
11616 else
11617 {
11618 Format(full_key_name, sizeof(full_key_name),
11619 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",
11620 key_name);
11621 }
11622
11623 // Read the DriverDesc
11624 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
11625 if (driver_desc != NULL)
11626 {
11627 if (StrCmpi(dest_name, driver_desc) == 0)
11628 {
11629 // Writing of the MAC address
11630 MsRegWriteStr(REG_LOCAL_MACHINE, full_key_name, "NetworkAddress", mac_str);
11631 Free(driver_desc);
11632
11633 // Restarting the driver
11634 MsRestartVLan(instance_name);
11635 break;
11636 }
11637 Free(driver_desc);
11638 }
11639 }
11640
11641 FreeToken(key_list);
11642
11643 return;
11644 }
11645
11646 // Get the file name of the device driver
MsGetDriverFileName(char * tag_name,char * instance_name)11647 char *MsGetDriverFileName(char *tag_name, char *instance_name)
11648 {
11649 TOKEN_LIST *key_list;
11650 UINT i;
11651 char *ret = NULL;
11652 char dest_name[MAX_SIZE];
11653 // Validate arguments
11654 if (tag_name == NULL || instance_name == NULL)
11655 {
11656 return NULL;
11657 }
11658
11659 // Generate the desired name
11660 Format(dest_name, sizeof(dest_name), tag_name, instance_name);
11661
11662 // Enumerate the key
11663 if (MsIsNt())
11664 {
11665 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11666 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
11667 }
11668 else
11669 {
11670 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11671 "System\\CurrentControlSet\\Services\\Class\\Net");
11672 }
11673 if (key_list == NULL)
11674 {
11675 return NULL;
11676 }
11677
11678 for (i = 0;i < key_list->NumTokens;i++)
11679 {
11680 char *key_name = key_list->Token[i];
11681 char full_key_name[MAX_SIZE];
11682 char *driver_desc;
11683
11684 if (MsIsNt())
11685 {
11686 Format(full_key_name, sizeof(full_key_name),
11687 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
11688 key_name);
11689 }
11690 else
11691 {
11692 Format(full_key_name, sizeof(full_key_name),
11693 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",
11694 key_name);
11695 }
11696
11697 // Read the DriverDesc
11698 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
11699 if (driver_desc != NULL)
11700 {
11701 if (StrCmpi(dest_name, driver_desc) == 0)
11702 {
11703 // Read the file name
11704 ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DeviceVxDs");
11705 Free(driver_desc);
11706 break;
11707 }
11708 Free(driver_desc);
11709 }
11710 }
11711
11712 FreeToken(key_list);
11713
11714 return ret;
11715 }
11716
11717 // Get the version of the device driver
MsGetDriverVersion(char * tag_name,char * instance_name)11718 char *MsGetDriverVersion(char *tag_name, char *instance_name)
11719 {
11720 TOKEN_LIST *key_list;
11721 TOKEN_LIST *t;
11722 UINT i;
11723 char *ret = NULL;
11724 char dest_name[MAX_SIZE];
11725 // Validate arguments
11726 if (tag_name == NULL || instance_name == NULL)
11727 {
11728 return NULL;
11729 }
11730
11731 // Generate the desired name
11732 Format(dest_name, sizeof(dest_name), tag_name, instance_name);
11733
11734 // Enumerate the key
11735 if (MsIsNt())
11736 {
11737 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11738 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
11739 }
11740 else
11741 {
11742 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11743 "System\\CurrentControlSet\\Services\\Class\\Net");
11744 }
11745 if (key_list == NULL)
11746 {
11747 return NULL;
11748 }
11749
11750 for (i = 0;i < key_list->NumTokens;i++)
11751 {
11752 char *key_name = key_list->Token[i];
11753 char full_key_name[MAX_SIZE];
11754 char *driver_desc;
11755
11756 if (MsIsNt())
11757 {
11758 Format(full_key_name, sizeof(full_key_name),
11759 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
11760 key_name);
11761 }
11762 else
11763 {
11764 Format(full_key_name, sizeof(full_key_name),
11765 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",
11766 key_name);
11767 }
11768
11769 // Read the DriverDesc
11770 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
11771 if (driver_desc != NULL)
11772 {
11773 if (StrCmpi(dest_name, driver_desc) == 0)
11774 {
11775 // Read the version information
11776 ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverVersion");
11777 if (ret == NULL)
11778 {
11779 ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NeoVersion");
11780 }
11781 Free(driver_desc);
11782 break;
11783 }
11784 Free(driver_desc);
11785 }
11786 }
11787
11788 FreeToken(key_list);
11789
11790 if (ret == NULL)
11791 {
11792 return NULL;
11793 }
11794
11795 t = ParseToken(ret, ", ");
11796 if (t->NumTokens == 2)
11797 {
11798 Free(ret);
11799 ret = CopyStr(t->Token[1]);
11800 }
11801 FreeToken(t);
11802
11803 return ret;
11804 }
11805
11806 // Get the registry key of the NETCFG of the virtual LAN card
MsGetNetCfgRegKeyName(char * tag_name,char * instance_name)11807 char *MsGetNetCfgRegKeyName(char *tag_name, char *instance_name)
11808 {
11809 TOKEN_LIST *key_list;
11810 UINT i;
11811 char *ret = NULL;
11812 char dest_name[MAX_SIZE];
11813 // Validate arguments
11814 if (tag_name == NULL || instance_name == NULL)
11815 {
11816 return NULL;
11817 }
11818
11819 // Generate the desired name
11820 Format(dest_name, sizeof(dest_name), tag_name, instance_name);
11821
11822 // Enumerate the key
11823 if (MsIsNt())
11824 {
11825 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11826 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
11827 }
11828 else
11829 {
11830 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11831 "System\\CurrentControlSet\\Services\\Class\\Net");
11832 }
11833
11834 if (key_list == NULL)
11835 {
11836 return NULL;
11837 }
11838
11839 for (i = 0;i < key_list->NumTokens;i++)
11840 {
11841 char *key_name = key_list->Token[i];
11842 char full_key_name[MAX_SIZE];
11843 char *driver_desc;
11844
11845 if (MsIsNt())
11846 {
11847 Format(full_key_name, sizeof(full_key_name),
11848 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
11849 key_name);
11850 }
11851 else
11852 {
11853 Format(full_key_name, sizeof(full_key_name),
11854 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",
11855 key_name);
11856 }
11857
11858 // Read the DriverDesc
11859 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
11860 if (driver_desc != NULL)
11861 {
11862 if (StrCmpi(dest_name, driver_desc) == 0)
11863 {
11864 ret = CopyStr(full_key_name);
11865
11866 Free(driver_desc);
11867 break;
11868 }
11869 Free(driver_desc);
11870 }
11871 }
11872
11873 FreeToken(key_list);
11874
11875 return ret;
11876 }
11877
11878 // Get the MAC address
MsGetMacAddress(char * tag_name,char * instance_name)11879 char *MsGetMacAddress(char *tag_name, char *instance_name)
11880 {
11881 TOKEN_LIST *key_list;
11882 UINT i;
11883 char *ret = NULL;
11884 char dest_name[MAX_SIZE];
11885 // Validate arguments
11886 if (tag_name == NULL || instance_name == NULL)
11887 {
11888 return NULL;
11889 }
11890
11891 // Generate the desired name
11892 Format(dest_name, sizeof(dest_name), tag_name, instance_name);
11893
11894 // Enumerate the key
11895 if (MsIsNt())
11896 {
11897 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11898 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
11899 }
11900 else
11901 {
11902 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
11903 "System\\CurrentControlSet\\Services\\Class\\Net");
11904 }
11905
11906 if (key_list == NULL)
11907 {
11908 return NULL;
11909 }
11910
11911 for (i = 0;i < key_list->NumTokens;i++)
11912 {
11913 char *key_name = key_list->Token[i];
11914 char full_key_name[MAX_SIZE];
11915 char *driver_desc;
11916
11917 if (MsIsNt())
11918 {
11919 Format(full_key_name, sizeof(full_key_name),
11920 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
11921 key_name);
11922 }
11923 else
11924 {
11925 Format(full_key_name, sizeof(full_key_name),
11926 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",
11927 key_name);
11928 }
11929
11930 // Read the DriverDesc
11931 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
11932 if (driver_desc != NULL)
11933 {
11934 if (StrCmpi(dest_name, driver_desc) == 0)
11935 {
11936 // Read the MAC address
11937 ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NetworkAddress");
11938
11939 if (IsEmptyStr(ret) == false)
11940 {
11941 // Insert hyphens between the MAC address elements
11942 BUF *b = StrToBin(ret);
11943 if (b != NULL && b->Size == 6)
11944 {
11945 char tmp[MAX_SIZE];
11946 MacToStr(tmp, sizeof(tmp), b->Buf);
11947
11948 Free(ret);
11949 ret = CopyStr(tmp);
11950 }
11951 FreeBuf(b);
11952 }
11953
11954 Free(driver_desc);
11955 break;
11956 }
11957 Free(driver_desc);
11958 }
11959 }
11960
11961 FreeToken(key_list);
11962
11963 return ret;
11964 }
11965
11966 // Check whether the device name of the virtual LAN card exists really
MsCheckVLanDeviceIdFromRootEnum(char * name)11967 bool MsCheckVLanDeviceIdFromRootEnum(char *name)
11968 {
11969 TOKEN_LIST *t;
11970 char *root;
11971 char *keyname;
11972 UINT i;
11973 bool ret;
11974 // Validate arguments
11975 if (name == NULL)
11976 {
11977 return false;
11978 }
11979
11980 if (MsIsNt())
11981 {
11982 root = "SYSTEM\\CurrentControlSet\\Enum\\Root\\NET";
11983 keyname = "HardwareID";
11984 }
11985 else
11986 {
11987 root = "Enum\\Root\\Net";
11988 keyname = "CompatibleIDs";
11989 }
11990
11991 t = MsRegEnumKey(REG_LOCAL_MACHINE, root);
11992 if (t == NULL)
11993 {
11994 return false;
11995 }
11996
11997 ret = false;
11998
11999 for (i = 0;i < t->NumTokens;i++)
12000 {
12001 char *subname = t->Token[i];
12002 char fullname[MAX_SIZE];
12003 char *value;
12004
12005 Format(fullname, sizeof(fullname), "%s\\%s", root, subname);
12006
12007 value = MsRegReadStr(REG_LOCAL_MACHINE, fullname, keyname);
12008 if (value != NULL)
12009 {
12010 if (StrCmpi(value, name) == 0)
12011 {
12012 ret = true;
12013 }
12014 Free(value);
12015 }
12016
12017 if (ret)
12018 {
12019 break;
12020 }
12021 }
12022
12023 FreeToken(t);
12024
12025 return ret;
12026 }
12027
12028 // Get the GUID of the network adapter
MsGetNetworkAdapterGuid(char * tag_name,char * instance_name)12029 char *MsGetNetworkAdapterGuid(char *tag_name, char *instance_name)
12030 {
12031 TOKEN_LIST *key_list;
12032 UINT i;
12033 char *ret = NULL;
12034 char dest_name[MAX_SIZE];
12035 // Validate arguments
12036 if (tag_name == NULL || instance_name == NULL)
12037 {
12038 return NULL;
12039 }
12040
12041 // Generate the desired name
12042 Format(dest_name, sizeof(dest_name), tag_name, instance_name);
12043
12044 // Enumerate the key
12045 if (MsIsNt())
12046 {
12047 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
12048 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
12049 }
12050 else
12051 {
12052 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
12053 "System\\CurrentControlSet\\Services\\Class\\Net");
12054 }
12055 if (key_list == NULL)
12056 {
12057 return NULL;
12058 }
12059
12060 for (i = 0;i < key_list->NumTokens;i++)
12061 {
12062 char *key_name = key_list->Token[i];
12063 char full_key_name[MAX_SIZE];
12064 char *driver_desc;
12065 char *device_id;
12066
12067 if (MsIsNt())
12068 {
12069 Format(full_key_name, sizeof(full_key_name),
12070 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
12071 key_name);
12072 }
12073 else
12074 {
12075 Format(full_key_name, sizeof(full_key_name),
12076 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",
12077 key_name);
12078 }
12079
12080 device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");
12081
12082 if (device_id != NULL)
12083 {
12084 if (MsCheckVLanDeviceIdFromRootEnum(device_id))
12085 {
12086 // Read the DriverDesc
12087 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
12088 if (driver_desc != NULL)
12089 {
12090 if (StrCmpi(dest_name, driver_desc) == 0)
12091 {
12092 // Read the NetCfgInstanceId
12093 if (MsIsNt())
12094 {
12095 ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NetCfgInstanceId");
12096 }
12097 else
12098 {
12099 ret = CopyStr("");
12100 }
12101 Free(driver_desc);
12102 Free(device_id);
12103 break;
12104 }
12105 Free(driver_desc);
12106 }
12107 }
12108 Free(device_id);
12109 }
12110 }
12111
12112 FreeToken(key_list);
12113
12114 return ret;
12115 }
12116 // Get the network connection name
MsGetNetworkConnectionName(char * guid)12117 wchar_t *MsGetNetworkConnectionName(char *guid)
12118 {
12119 wchar_t *ncname = NULL;
12120 // Validate arguments
12121 if (guid == NULL)
12122 {
12123 return NULL;
12124 }
12125
12126 // Get the network connection name
12127 if (IsNt() != false && GetOsInfo()->OsType >= OSTYPE_WINDOWS_2000_PROFESSIONAL)
12128 {
12129 char tmp[MAX_SIZE];
12130 Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", guid);
12131 ncname = MsRegReadStrW(REG_LOCAL_MACHINE, tmp, "Name");
12132 }
12133
12134 return ncname;
12135 }
12136
12137 // Generate driver file name for the new Neo
MsMakeNewNeoDriverFilename(char * name,UINT size)12138 bool MsMakeNewNeoDriverFilename(char *name, UINT size)
12139 {
12140 TOKEN_LIST *t = MsEnumNeoDriverFilenames();
12141 UINT i;
12142 bool ret = false;
12143
12144 i = 0;
12145 while (true)
12146 {
12147 char tmp[MAX_PATH];
12148 UINT n;
12149
12150 i++;
12151 if (i >= 10000)
12152 {
12153 break;
12154 }
12155
12156 n = Rand32() % DRIVER_INSTALL_SYS_NAME_TAG_MAXID;
12157
12158 MsGenerateNeoDriverFilenameFromInt(tmp, sizeof(tmp), n);
12159
12160 if (IsInToken(t, tmp) == false)
12161 {
12162 StrCpy(name, size, tmp);
12163 ret = true;
12164 break;
12165 }
12166 }
12167
12168 FreeToken(t);
12169
12170 return ret;
12171 }
12172
12173 // Generate the driver file name of Neo from a integer
MsGenerateNeoDriverFilenameFromInt(char * name,UINT size,UINT n)12174 void MsGenerateNeoDriverFilenameFromInt(char *name, UINT size, UINT n)
12175 {
12176 Format(name, size, DRIVER_INSTALL_SYS_NAME_TAG_NEW, n);
12177 }
12178
12179 // Enumeration of the driver file names of installed Neo
MsEnumNeoDriverFilenames()12180 TOKEN_LIST *MsEnumNeoDriverFilenames()
12181 {
12182 TOKEN_LIST *neos = MsEnumNetworkAdaptersNeo();
12183 LIST *o = NewListFast(NULL);
12184 TOKEN_LIST *ret;
12185 UINT i;
12186
12187 for (i = 0;i < neos->NumTokens;i++)
12188 {
12189 char filename[MAX_PATH];
12190 if (MsGetNeoDeiverFilename(filename, sizeof(filename), neos->Token[i]))
12191 {
12192 Add(o, CopyStr(filename));
12193 }
12194 }
12195
12196 FreeToken(neos);
12197
12198 ret = ListToTokenList(o);
12199 FreeStrList(o);
12200
12201 return ret;
12202 }
12203
12204 // Get the driver file name of Neo
MsGetNeoDeiverFilename(char * name,UINT size,char * instance_name)12205 bool MsGetNeoDeiverFilename(char *name, UINT size, char *instance_name)
12206 {
12207 char tmp[MAX_SIZE];
12208 char *ret;
12209 // Validate arguments
12210 if (name == NULL || instance_name == NULL)
12211 {
12212 return false;
12213 }
12214
12215 Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Services\\Neo_%s", instance_name);
12216
12217 ret = MsRegReadStr(REG_LOCAL_MACHINE, tmp, "ImagePath");
12218 if (ret == NULL)
12219 {
12220 return false;
12221 }
12222
12223 GetFileNameFromFilePath(name, size, ret);
12224 Free(ret);
12225
12226 return true;
12227 }
12228
12229 // Enumeration of the network adapter (only Neo)
MsEnumNetworkAdaptersNeo()12230 TOKEN_LIST *MsEnumNetworkAdaptersNeo()
12231 {
12232 TOKEN_LIST *key_list;
12233 TOKEN_LIST *ret;
12234 LIST *o;
12235 UINT i;
12236
12237 // Enumerate the key
12238 if (MsIsNt())
12239 {
12240 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
12241 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
12242 }
12243 else
12244 {
12245 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
12246 "System\\CurrentControlSet\\Services\\Class\\Net");
12247 }
12248 if (key_list == NULL)
12249 {
12250 return NULL;
12251 }
12252
12253 o = NewListFast(CompareStr);
12254
12255 for (i = 0;i < key_list->NumTokens;i++)
12256 {
12257 char *key_name = key_list->Token[i];
12258 char full_key_name[MAX_SIZE];
12259 char *driver_desc;
12260 char *device_id;
12261
12262 if (MsIsNt())
12263 {
12264 Format(full_key_name, sizeof(full_key_name),
12265 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
12266 key_name);
12267 }
12268 else
12269 {
12270 Format(full_key_name, sizeof(full_key_name),
12271 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",
12272 key_name);
12273 }
12274
12275 // Read the DriverDesc
12276 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
12277 if (driver_desc != NULL)
12278 {
12279 // Check whether it starts with the specific name
12280 device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");
12281
12282 if (device_id != NULL)
12283 {
12284 if (MsCheckVLanDeviceIdFromRootEnum(device_id))
12285 {
12286 char *tag = "neoadapter_";
12287 if (StartWith(device_id, tag))
12288 {
12289 char tmp[MAX_SIZE];
12290 StrCpy(tmp, sizeof(tmp), &device_id[StrLen(tag)]);
12291
12292 Add(o, CopyStr(tmp));
12293 }
12294 }
12295 Free(device_id);
12296 }
12297
12298 Free(driver_desc);
12299 }
12300 }
12301
12302 FreeToken(key_list);
12303
12304 ret = ZeroMalloc(sizeof(TOKEN_LIST));
12305 ret->NumTokens = LIST_NUM(o);
12306 ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
12307 for (i = 0;i < ret->NumTokens;i++)
12308 {
12309 ret->Token[i] = LIST_DATA(o, i);
12310 }
12311
12312 ReleaseList(o);
12313
12314 return ret;
12315 }
12316
12317 // Enumeration of the network adapter
MsEnumNetworkAdapters(char * start_with_name,char * start_with_name_2)12318 TOKEN_LIST *MsEnumNetworkAdapters(char *start_with_name, char *start_with_name_2)
12319 {
12320 TOKEN_LIST *key_list;
12321 TOKEN_LIST *ret;
12322 LIST *o;
12323 UINT i;
12324
12325 // Enumerate the key
12326 if (MsIsNt())
12327 {
12328 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
12329 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
12330 }
12331 else
12332 {
12333 key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
12334 "System\\CurrentControlSet\\Services\\Class\\Net");
12335 }
12336 if (key_list == NULL)
12337 {
12338 return NULL;
12339 }
12340
12341 o = NewListFast(CompareStr);
12342
12343 for (i = 0;i < key_list->NumTokens;i++)
12344 {
12345 char *key_name = key_list->Token[i];
12346 char full_key_name[MAX_SIZE];
12347 char *driver_desc;
12348 char *device_id;
12349
12350 if (MsIsNt())
12351 {
12352 Format(full_key_name, sizeof(full_key_name),
12353 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
12354 key_name);
12355 }
12356 else
12357 {
12358 Format(full_key_name, sizeof(full_key_name),
12359 "System\\CurrentControlSet\\Services\\Class\\Net\\%s",
12360 key_name);
12361 }
12362
12363 // Read the DriverDesc
12364 driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
12365 if (driver_desc != NULL)
12366 {
12367 // Check whether it starts with the specific name
12368 if ((IsEmptyStr(start_with_name) && IsEmptyStr(start_with_name_2)) ||
12369 (StartWith(driver_desc, start_with_name) || StartWith(driver_desc, start_with_name_2)))
12370 {
12371 device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");
12372
12373 if (device_id != NULL)
12374 {
12375 if (MsCheckVLanDeviceIdFromRootEnum(device_id))
12376 {
12377 char instance_name[MAX_SIZE];
12378 // Extract only the instance name from the name
12379 if (StartWith(driver_desc, start_with_name))
12380 {
12381 if (StrLen(driver_desc) > (StrLen(start_with_name) + 3))
12382 {
12383 StrCpy(instance_name, sizeof(instance_name),
12384 driver_desc + StrLen(start_with_name) + 3);
12385 Add(o, CopyStr(instance_name));
12386 }
12387 }
12388 else
12389 {
12390 if (StrLen(driver_desc) > (StrLen(start_with_name_2) + 3))
12391 {
12392 StrCpy(instance_name, sizeof(instance_name),
12393 driver_desc + StrLen(start_with_name_2) + 3);
12394 Add(o, CopyStr(instance_name));
12395 }
12396 }
12397 }
12398 Free(device_id);
12399 }
12400 }
12401
12402 Free(driver_desc);
12403 }
12404 }
12405
12406 FreeToken(key_list);
12407
12408 ret = ZeroMalloc(sizeof(TOKEN_LIST));
12409 ret->NumTokens = LIST_NUM(o);
12410 ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
12411 for (i = 0;i < ret->NumTokens;i++)
12412 {
12413 ret->Token[i] = LIST_DATA(o, i);
12414 }
12415
12416 ReleaseList(o);
12417
12418 return ret;
12419 }
12420
12421 // Attempt to logon to the domain
MsCheckLogon(wchar_t * username,char * password)12422 bool MsCheckLogon(wchar_t *username, char *password)
12423 {
12424 wchar_t password_unicode[MAX_SIZE];
12425 HANDLE h;
12426 // Validate arguments
12427 if (username == NULL || password == NULL)
12428 {
12429 return false;
12430 }
12431
12432 if (MsIsNt() == false)
12433 {
12434 return false;
12435 }
12436
12437 StrToUni(password_unicode, sizeof(password_unicode), password);
12438
12439 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
12440 {
12441 if (ms->nt->LogonUserW(username, NULL, password_unicode, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)
12442 {
12443 // Logon failure
12444 return false;
12445 }
12446 }
12447 else
12448 {
12449 char username_ansi[MAX_SIZE];
12450 UniToStr(username_ansi, sizeof(username_ansi), username);
12451
12452 if (ms->nt->LogonUserA(username_ansi, NULL, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)
12453 {
12454 // Logon failure
12455 return false;
12456 }
12457 }
12458
12459 CloseHandle(h);
12460
12461 return true;
12462 }
12463
12464 // Attempt to logon to the domain
MsIsPasswordEmpty(wchar_t * username)12465 bool MsIsPasswordEmpty(wchar_t *username)
12466 {
12467 HANDLE h;
12468 // Validate arguments
12469 if (username == NULL)
12470 {
12471 return false;
12472 }
12473
12474 if (MsIsNt() == false)
12475 {
12476 return false;
12477 }
12478
12479 if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
12480 {
12481 if (ms->nt->LogonUserW(username, NULL, L"", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)
12482 {
12483 // Logon failure
12484 if (GetLastError() == 1327)
12485 {
12486 // Password is empty
12487 return true;
12488 }
12489 else
12490 {
12491 // The password is not correct
12492 return false;
12493 }
12494 }
12495 }
12496 else
12497 {
12498 char username_ansi[MAX_SIZE];
12499 UniToStr(username_ansi, sizeof(username_ansi), username);
12500
12501 if (ms->nt->LogonUserA(username_ansi, NULL, "", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)
12502 {
12503 // Logon failure
12504 if (GetLastError() == 1327)
12505 {
12506 // Password is empty
12507 return true;
12508 }
12509 else
12510 {
12511 // The password is not correct
12512 return false;
12513 }
12514 }
12515 }
12516
12517 CloseHandle(h);
12518
12519 // Since successful logon, the password should be empty
12520 return false;
12521 }
12522
12523 // Determine if the workstation is locked by using WTS API
MsDetermineIsLockedByWtsApi()12524 bool MsDetermineIsLockedByWtsApi()
12525 {
12526 return wts_is_locked_flag;
12527 }
12528
12529 // IsLocked Window Proc
MsIsLockedWindowHandlerWindowProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)12530 LRESULT CALLBACK MsIsLockedWindowHandlerWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
12531 {
12532 MS_ISLOCKED *d = NULL;
12533 CREATESTRUCT *cs;
12534 // Validate arguments
12535 if (hWnd == NULL)
12536 {
12537 return 0;
12538 }
12539
12540 d = (MS_ISLOCKED *)GetWindowLongPtrA(hWnd, GWLP_USERDATA);
12541 if (d == NULL && msg != WM_CREATE)
12542 {
12543 goto LABEL_END;
12544 }
12545
12546 switch (msg)
12547 {
12548 case WM_CREATE:
12549 cs = (CREATESTRUCT *)lParam;
12550 d = (MS_ISLOCKED *)cs->lpCreateParams;
12551 SetWindowLongPtrA(hWnd, GWLP_USERDATA, (LONG_PTR)d);
12552
12553 ms->nt->WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
12554
12555 wts_is_locked_flag = false;
12556
12557 break;
12558
12559 case WM_WTSSESSION_CHANGE:
12560 {
12561 char tmp[MAX_SIZE];
12562
12563 GetDateTimeStr64(tmp, sizeof(tmp), LocalTime64());
12564
12565 switch (wParam)
12566 {
12567 case WTS_SESSION_LOCK:
12568 Debug("%s: Enter Lock\n", tmp);
12569 d->IsLockedFlag = true;
12570 wts_is_locked_flag = true;
12571 break;
12572
12573 case WTS_SESSION_UNLOCK:
12574 Debug("%s: Enter Unlock\n", tmp);
12575 d->IsLockedFlag = false;
12576 wts_is_locked_flag = false;
12577 break;
12578 }
12579 }
12580
12581 break;
12582
12583 case WM_DESTROY:
12584 Debug("Unregister\n");
12585 ms->nt->WTSUnRegisterSessionNotification(hWnd);
12586 PostQuitMessage(0);
12587 break;
12588 }
12589
12590 LABEL_END:
12591 return DefWindowProc(hWnd, msg, wParam, lParam);
12592 }
12593
12594 // IsLocked thread proc
MsIsLockedThreadProc(THREAD * thread,void * param)12595 void MsIsLockedThreadProc(THREAD *thread, void *param)
12596 {
12597 MS_ISLOCKED *d = (MS_ISLOCKED *)param;
12598 char wndclass_name[MAX_PATH];
12599 WNDCLASS wc;
12600 HWND hWnd;
12601 MSG msg;
12602 // Validate arguments
12603 if (d == NULL || thread == NULL)
12604 {
12605 return;
12606 }
12607
12608 Format(wndclass_name, sizeof(wndclass_name), "WNDCLASS_%X", Rand32());
12609
12610 Zero(&wc, sizeof(wc));
12611 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
12612 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
12613 wc.hIcon = NULL;
12614 wc.hInstance = ms->hInst;
12615 wc.lpfnWndProc = MsIsLockedWindowHandlerWindowProc;
12616 wc.lpszClassName = wndclass_name;
12617 if (RegisterClassA(&wc) == 0)
12618 {
12619 NoticeThreadInit(thread);
12620 return;
12621 }
12622
12623 hWnd = CreateWindowA(wndclass_name, wndclass_name, WS_OVERLAPPEDWINDOW,
12624 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
12625 NULL, NULL, ms->hInst, d);
12626
12627 d->hWnd = hWnd;
12628
12629 NoticeThreadInit(thread);
12630
12631 if (hWnd == NULL)
12632 {
12633 UnregisterClassA(wndclass_name, ms->hInst);
12634 return;
12635 }
12636
12637 while (GetMessage(&msg, NULL, 0, 0))
12638 {
12639 TranslateMessage(&msg);
12640 DispatchMessage(&msg);
12641 }
12642
12643 DestroyWindow(hWnd);
12644
12645 UnregisterClassA(wndclass_name, ms->hInst);
12646 }
12647
12648 // Create new IsLocked thread
MsNewIsLocked()12649 MS_ISLOCKED *MsNewIsLocked()
12650 {
12651 MS_ISLOCKED *d;
12652 THREAD *t;
12653
12654 SleepThread(5000);
12655
12656 if (IsNt() == false || ms->nt->WTSRegisterSessionNotification == NULL ||
12657 ms->nt->WTSUnRegisterSessionNotification == NULL)
12658 {
12659 return NULL;
12660 }
12661
12662 d = ZeroMalloc(sizeof(MS_ISLOCKED));
12663
12664 t = NewThread(MsIsLockedThreadProc, d);
12665
12666 WaitThreadInit(t);
12667
12668 d->Thread = t;
12669
12670 return d;
12671 }
12672
12673 // Stop and free the IsLocked thread
MsFreeIsLocked(MS_ISLOCKED * d)12674 void MsFreeIsLocked(MS_ISLOCKED *d)
12675 {
12676 if (d == NULL)
12677 {
12678 return;
12679 }
12680
12681 if (d->hWnd != NULL)
12682 {
12683 PostMessageA(d->hWnd, WM_CLOSE, 0, 0);
12684 }
12685
12686 WaitThread(d->Thread, INFINITE);
12687 ReleaseThread(d->Thread);
12688
12689 Free(d);
12690 }
12691
12692 // Execution of shutdown (NT)
MsShutdownEx(bool reboot,bool force,UINT time_limit,char * message)12693 bool MsShutdownEx(bool reboot, bool force, UINT time_limit, char *message)
12694 {
12695 if (MsIsNt() == false)
12696 {
12697 return MsShutdown(reboot, force);
12698 }
12699
12700 // Get the privilege
12701 if (MsEnablePrivilege(SE_SHUTDOWN_NAME, true) == false)
12702 {
12703 return false;
12704 }
12705
12706 // Execute the shutdown
12707 if (ms->nt->InitiateSystemShutdown(NULL, message, time_limit, force, reboot) == false)
12708 {
12709 MsEnablePrivilege(SE_SHUTDOWN_NAME, false);
12710 return false;
12711 }
12712
12713 // Release of privilege
12714 MsEnablePrivilege(SE_SHUTDOWN_NAME, false);
12715
12716 return true;
12717 }
12718
12719 // Execute the shutdown
MsShutdown(bool reboot,bool force)12720 bool MsShutdown(bool reboot, bool force)
12721 {
12722 UINT flag = 0;
12723 // Get the privilege
12724 if (MsEnablePrivilege(SE_SHUTDOWN_NAME, true) == false)
12725 {
12726 return false;
12727 }
12728
12729 flag |= (reboot ? EWX_REBOOT : EWX_SHUTDOWN);
12730 flag |= (force ? EWX_FORCE : 0);
12731
12732 // Execute the shutdown
12733 if (ExitWindowsEx(flag, 0) == false)
12734 {
12735 MsEnablePrivilege(SE_SHUTDOWN_NAME, false);
12736 return false;
12737 }
12738
12739 // Release of privilege
12740 MsEnablePrivilege(SE_SHUTDOWN_NAME, false);
12741
12742 return true;
12743 }
12744
12745 // Enable or disable the privilege
MsEnablePrivilege(char * name,bool enable)12746 bool MsEnablePrivilege(char *name, bool enable)
12747 {
12748 HANDLE hToken;
12749 NT_API *nt = ms->nt;
12750 LUID luid;
12751 TOKEN_PRIVILEGES *tp;
12752 bool ret;
12753 // Validate arguments
12754 if (name == NULL)
12755 {
12756 return false;
12757 }
12758 if (MsIsNt() == false)
12759 {
12760 return true;
12761 }
12762
12763 // Open the process token
12764 if (nt->OpenProcessToken(ms->hCurrentProcess, TOKEN_ADJUST_PRIVILEGES, &hToken) == false)
12765 {
12766 return false;
12767 }
12768
12769 // Get a local unique identifier
12770 if (nt->LookupPrivilegeValue(NULL, name, &luid) == FALSE)
12771 {
12772 CloseHandle(hToken);
12773 return false;
12774 }
12775
12776 // Create a structure to enable / disable the privilege
12777 tp = ZeroMalloc(sizeof(TOKEN_PRIVILEGES));
12778 tp->PrivilegeCount = 1;
12779 tp->Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
12780 Copy(&tp->Privileges[0].Luid, &luid, sizeof(LUID));
12781
12782 // Manipulate the privilege
12783 ret = nt->AdjustTokenPrivileges(hToken, false, tp, sizeof(TOKEN_PRIVILEGES), 0, 0);
12784
12785 Free(tp);
12786 CloseHandle(hToken);
12787
12788 return ret;
12789 }
12790
12791 // Get whether the current OS is a NT system
MsIsNt()12792 bool MsIsNt()
12793 {
12794 if (ms == NULL)
12795 {
12796 OSVERSIONINFO os;
12797 Zero(&os, sizeof(os));
12798 os.dwOSVersionInfoSize = sizeof(os);
12799 GetVersionEx(&os);
12800 if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
12801 {
12802 return true;
12803 }
12804 else
12805 {
12806 return false;
12807 }
12808 }
12809
12810 return ms->IsNt;
12811 }
12812
12813 // Get whether the current system is WINE
MsIsWine()12814 bool MsIsWine()
12815 {
12816 bool ret = false;
12817
12818 if (ms == NULL)
12819 {
12820 HINSTANCE h = LoadLibrary("kernel32.dll");
12821
12822 if (h != NULL)
12823 {
12824 if (GetProcAddress(h, "wine_get_unix_file_name") != NULL)
12825 {
12826 ret = true;
12827 }
12828
12829 FreeLibrary(h);
12830 }
12831 }
12832 else
12833 {
12834 ret = ms->IsWine;
12835 }
12836
12837 return ret;
12838 }
12839
12840 // Get whether the current user is an Admin
MsIsAdmin()12841 bool MsIsAdmin()
12842 {
12843 return ms->IsAdmin;
12844 }
12845
12846 // Load the NT system function
MsLoadNtApiFunctions()12847 NT_API *MsLoadNtApiFunctions()
12848 {
12849 NT_API *nt = ZeroMalloc(sizeof(NT_API));
12850 OSVERSIONINFO info;
12851
12852 Zero(&info, sizeof(info));
12853 info.dwOSVersionInfoSize = sizeof(info);
12854 GetVersionEx(&info);
12855
12856 nt->hKernel32 = LoadLibrary("kernel32.dll");
12857 if (nt->hKernel32 == NULL)
12858 {
12859 Free(nt);
12860 return NULL;
12861 }
12862
12863 nt->hAdvapi32 = LoadLibrary("advapi32.dll");
12864 if (nt->hAdvapi32 == NULL)
12865 {
12866 Free(nt);
12867 return NULL;
12868 }
12869
12870 nt->hShell32 = LoadLibrary("shell32.dll");
12871 if (nt->hShell32 == NULL)
12872 {
12873 FreeLibrary(nt->hAdvapi32);
12874 Free(nt);
12875 return NULL;
12876 }
12877
12878 nt->hPsApi = LoadLibrary("psapi.dll");
12879
12880 if (info.dwMajorVersion >= 5)
12881 {
12882 nt->hNewDev = LoadLibrary("newdev.dll");
12883 if (nt->hNewDev == NULL)
12884 {
12885 FreeLibrary(nt->hShell32);
12886 FreeLibrary(nt->hAdvapi32);
12887 Free(nt);
12888 return NULL;
12889 }
12890
12891 nt->hSetupApi = LoadLibrary("setupapi.dll");
12892 }
12893
12894 nt->hSecur32 = LoadLibrary("secur32.dll");
12895
12896 nt->hUser32 = LoadLibrary("user32.dll");
12897
12898 nt->hDbgHelp = LoadLibrary("dbghelp.dll");
12899
12900 nt->hWcmapi = LoadLibrary("wcmapi.dll");
12901
12902 nt->hDwmapi = LoadLibrary("dwmapi.dll");
12903
12904 // Read the function
12905 nt->GetComputerNameExW =
12906 (BOOL (__stdcall *)(COMPUTER_NAME_FORMAT,LPWSTR,LPDWORD))
12907 GetProcAddress(nt->hKernel32, "GetComputerNameExW");
12908
12909 nt->IsWow64Process =
12910 (BOOL (__stdcall *)(HANDLE,BOOL *))
12911 GetProcAddress(nt->hKernel32, "IsWow64Process");
12912
12913 nt->GetFileInformationByHandle =
12914 (BOOL (__stdcall *)(HANDLE,LPBY_HANDLE_FILE_INFORMATION))
12915 GetProcAddress(nt->hKernel32, "GetFileInformationByHandle");
12916
12917 nt->GetProcessHeap =
12918 (HANDLE (__stdcall *)())
12919 GetProcAddress(nt->hKernel32, "GetProcessHeap");
12920
12921 nt->SetProcessShutdownParameters =
12922 (BOOL (__stdcall *)(DWORD,DWORD))
12923 GetProcAddress(nt->hKernel32, "SetProcessShutdownParameters");
12924
12925 nt->GetNativeSystemInfo =
12926 (void (__stdcall *)(SYSTEM_INFO *))
12927 GetProcAddress(nt->hKernel32, "GetNativeSystemInfo");
12928
12929 nt->AdjustTokenPrivileges =
12930 (BOOL (__stdcall *)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD))
12931 GetProcAddress(nt->hAdvapi32, "AdjustTokenPrivileges");
12932
12933 nt->LookupPrivilegeValue =
12934 (BOOL (__stdcall *)(char *,char *,PLUID))
12935 GetProcAddress(nt->hAdvapi32, "LookupPrivilegeValueA");
12936
12937 nt->OpenProcessToken =
12938 (BOOL (__stdcall *)(HANDLE,DWORD,PHANDLE))
12939 GetProcAddress(nt->hAdvapi32, "OpenProcessToken");
12940
12941 nt->InitiateSystemShutdown =
12942 (BOOL (__stdcall *)(LPTSTR,LPTSTR,DWORD,BOOL,BOOL))
12943 GetProcAddress(nt->hAdvapi32, "InitiateSystemShutdownA");
12944
12945 nt->LogonUserW =
12946 (BOOL (__stdcall *)(wchar_t *,wchar_t *,wchar_t *,DWORD,DWORD,HANDLE *))
12947 GetProcAddress(nt->hAdvapi32, "LogonUserW");
12948
12949 nt->LogonUserA =
12950 (BOOL (__stdcall *)(char *,char *,char *,DWORD,DWORD,HANDLE * ))
12951 GetProcAddress(nt->hAdvapi32, "LogonUserA");
12952
12953 nt->DuplicateTokenEx =
12954 (BOOL (__stdcall *)(HANDLE,DWORD,SECURITY_ATTRIBUTES *,SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,HANDLE *))
12955 GetProcAddress(nt->hAdvapi32, "DuplicateTokenEx");
12956
12957 nt->ConvertStringSidToSidA =
12958 (BOOL (__stdcall *)(LPCSTR,PSID *))
12959 GetProcAddress(nt->hAdvapi32, "ConvertStringSidToSidA");
12960
12961 nt->GetTokenInformation =
12962 (BOOL (__stdcall *)(HANDLE,TOKEN_INFORMATION_CLASS,void *,DWORD,PDWORD))
12963 GetProcAddress(nt->hAdvapi32, "GetTokenInformation");
12964
12965 nt->SetTokenInformation =
12966 (BOOL (__stdcall *)(HANDLE,TOKEN_INFORMATION_CLASS,void *,DWORD))
12967 GetProcAddress(nt->hAdvapi32, "SetTokenInformation");
12968
12969 nt->CreateProcessAsUserA =
12970 (BOOL (__stdcall *)(HANDLE,LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,void *,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION))
12971 GetProcAddress(nt->hAdvapi32, "CreateProcessAsUserA");
12972
12973 nt->CreateProcessAsUserW =
12974 (BOOL (__stdcall *)(HANDLE,LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,void *,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION))
12975 GetProcAddress(nt->hAdvapi32, "CreateProcessAsUserW");
12976
12977 nt->LookupAccountSidA =
12978 (BOOL (__stdcall *)(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE))
12979 GetProcAddress(nt->hAdvapi32, "LookupAccountSidA");
12980
12981 nt->LookupAccountNameA =
12982 (BOOL (__stdcall *)(LPCSTR,LPCSTR,PSID,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE))
12983 GetProcAddress(nt->hAdvapi32, "LookupAccountNameA");
12984
12985 nt->SetNamedSecurityInfoW =
12986 (DWORD (__stdcall *)(LPWSTR,UINT,SECURITY_INFORMATION,PSID,PSID,PACL,PACL))
12987 GetProcAddress(nt->hAdvapi32, "SetNamedSecurityInfoW");
12988
12989 nt->AddAccessAllowedAceEx =
12990 (BOOL (__stdcall *)(PACL,DWORD,DWORD,DWORD,PSID))
12991 GetProcAddress(nt->hAdvapi32, "AddAccessAllowedAceEx");
12992
12993 nt->QueryFullProcessImageNameA =
12994 (BOOL (__stdcall *)(HANDLE,DWORD,LPSTR,PDWORD))
12995 GetProcAddress(nt->hKernel32, "QueryFullProcessImageNameA");
12996
12997 nt->QueryFullProcessImageNameW =
12998 (BOOL (__stdcall *)(HANDLE,DWORD,LPWSTR,PDWORD))
12999 GetProcAddress(nt->hKernel32, "QueryFullProcessImageNameW");
13000
13001 nt->RegLoadKeyW =
13002 (LSTATUS (__stdcall *)(HKEY,LPCWSTR,LPCWSTR))
13003 GetProcAddress(nt->hAdvapi32, "RegLoadKeyW");
13004
13005 nt->RegUnLoadKeyW =
13006 (LSTATUS (__stdcall *)(HKEY,LPCWSTR))
13007 GetProcAddress(nt->hAdvapi32, "RegUnLoadKeyW");
13008
13009 if (info.dwMajorVersion >= 5)
13010 {
13011 nt->UpdateDriverForPlugAndPlayDevicesW =
13012 (BOOL (__stdcall *)(HWND,wchar_t *,wchar_t *,UINT,BOOL *))
13013 GetProcAddress(nt->hNewDev, "UpdateDriverForPlugAndPlayDevicesW");
13014
13015 nt->CM_Get_Device_ID_ExA =
13016 (UINT (__stdcall *)(DWORD,char *,UINT,UINT,HANDLE))
13017 GetProcAddress(nt->hSetupApi, "CM_Get_Device_ID_ExA");
13018
13019 nt->CM_Get_DevNode_Status_Ex =
13020 (UINT (__stdcall *)(UINT *,UINT *,DWORD,UINT,HANDLE))
13021 GetProcAddress(nt->hSetupApi, "CM_Get_DevNode_Status_Ex");
13022 }
13023
13024 nt->hWtsApi32 = LoadLibrary("wtsapi32.dll");
13025 if (nt->hWtsApi32 != NULL)
13026 {
13027 // Terminal Services related API
13028 nt->WTSQuerySessionInformation =
13029 (UINT (__stdcall *)(HANDLE,DWORD,WTS_INFO_CLASS,wchar_t *,DWORD *))
13030 GetProcAddress(nt->hWtsApi32, "WTSQuerySessionInformationW");
13031 nt->WTSFreeMemory =
13032 (void (__stdcall *)(void *))
13033 GetProcAddress(nt->hWtsApi32, "WTSFreeMemory");
13034 nt->WTSDisconnectSession =
13035 (BOOL (__stdcall *)(HANDLE,DWORD,BOOL))
13036 GetProcAddress(nt->hWtsApi32, "WTSDisconnectSession");
13037 nt->WTSEnumerateSessionsA =
13038 (BOOL (__stdcall *)(HANDLE,DWORD,DWORD,PWTS_SESSION_INFOA *,DWORD *))
13039 GetProcAddress(nt->hWtsApi32, "WTSEnumerateSessionsA");
13040 nt->WTSRegisterSessionNotification =
13041 (BOOL (__stdcall *)(HWND,DWORD))
13042 GetProcAddress(nt->hWtsApi32, "WTSRegisterSessionNotification");
13043 nt->WTSUnRegisterSessionNotification =
13044 (BOOL (__stdcall *)(HWND))
13045 GetProcAddress(nt->hWtsApi32, "WTSUnRegisterSessionNotification");
13046 }
13047
13048 // Service related API
13049 nt->OpenSCManager =
13050 (SC_HANDLE (__stdcall *)(LPCTSTR,LPCTSTR,DWORD))
13051 GetProcAddress(nt->hAdvapi32, "OpenSCManagerA");
13052 nt->CreateServiceA =
13053 (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCTSTR,LPCTSTR,DWORD,DWORD,DWORD,DWORD,LPCTSTR,LPCTSTR,LPDWORD,LPCTSTR,LPCTSTR,LPCTSTR))
13054 GetProcAddress(nt->hAdvapi32, "CreateServiceA");
13055 nt->CreateServiceW =
13056 (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCWSTR,LPCWSTR,DWORD,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,LPDWORD,LPCWSTR,LPCWSTR,LPCWSTR))
13057 GetProcAddress(nt->hAdvapi32, "CreateServiceW");
13058 nt->ChangeServiceConfig2 =
13059 (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPVOID))
13060 GetProcAddress(nt->hAdvapi32, "ChangeServiceConfig2W");
13061 nt->CloseServiceHandle =
13062 (BOOL (__stdcall *)(SC_HANDLE))
13063 GetProcAddress(nt->hAdvapi32, "CloseServiceHandle");
13064 nt->OpenService =
13065 (SC_HANDLE (__stdcall *)(SC_HANDLE,LPCTSTR,DWORD))
13066 GetProcAddress(nt->hAdvapi32, "OpenServiceA");
13067 nt->QueryServiceStatus =
13068 (BOOL (__stdcall *)(SC_HANDLE,LPSERVICE_STATUS))
13069 GetProcAddress(nt->hAdvapi32, "QueryServiceStatus");
13070 nt->StartService =
13071 (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPCTSTR))
13072 GetProcAddress(nt->hAdvapi32, "StartServiceA");
13073 nt->ControlService =
13074 (BOOL (__stdcall *)(SC_HANDLE,DWORD,LPSERVICE_STATUS))
13075 GetProcAddress(nt->hAdvapi32, "ControlService");
13076 nt->SetServiceStatus =
13077 (BOOL (__stdcall *)(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS))
13078 GetProcAddress(nt->hAdvapi32, "SetServiceStatus");
13079 nt->RegisterServiceCtrlHandler =
13080 (SERVICE_STATUS_HANDLE (__stdcall *)(LPCTSTR,LPHANDLER_FUNCTION))
13081 GetProcAddress(nt->hAdvapi32, "RegisterServiceCtrlHandlerW");
13082 nt->StartServiceCtrlDispatcher =
13083 (BOOL (__stdcall *)(const LPSERVICE_TABLE_ENTRY))
13084 GetProcAddress(nt->hAdvapi32, "StartServiceCtrlDispatcherW");
13085 nt->DeleteService =
13086 (BOOL (__stdcall *)(SC_HANDLE))
13087 GetProcAddress(nt->hAdvapi32, "DeleteService");
13088 nt->RegisterEventSourceW =
13089 (HANDLE (__stdcall *)(LPCWSTR,LPCWSTR))
13090 GetProcAddress(nt->hAdvapi32, "RegisterEventSourceW");
13091 nt->ReportEventW =
13092 (BOOL (__stdcall *)(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR *,LPVOID))
13093 GetProcAddress(nt->hAdvapi32, "ReportEventW");
13094 nt->DeregisterEventSource =
13095 (BOOL (__stdcall *)(HANDLE))
13096 GetProcAddress(nt->hAdvapi32, "DeregisterEventSource");
13097 nt->Wow64DisableWow64FsRedirection =
13098 (BOOL (__stdcall *)(void **))
13099 GetProcAddress(nt->hKernel32, "Wow64DisableWow64FsRedirection");
13100 nt->Wow64EnableWow64FsRedirection =
13101 (BOOLEAN (__stdcall *)(BOOLEAN))
13102 GetProcAddress(nt->hKernel32, "Wow64EnableWow64FsRedirection");
13103 nt->Wow64RevertWow64FsRedirection =
13104 (BOOL (__stdcall *)(void *))
13105 GetProcAddress(nt->hKernel32, "Wow64RevertWow64FsRedirection");
13106
13107 if (nt->hPsApi != NULL)
13108 {
13109 // Process related API
13110 nt->EnumProcesses =
13111 (BOOL (__stdcall *)(DWORD *,DWORD,DWORD *))
13112 GetProcAddress(nt->hPsApi, "EnumProcesses");
13113
13114 nt->EnumProcessModules =
13115 (BOOL (__stdcall *)(HANDLE,HMODULE * ,DWORD,DWORD *))
13116 GetProcAddress(nt->hPsApi, "EnumProcessModules");
13117
13118 nt->GetModuleFileNameExA =
13119 (DWORD (__stdcall *)(HANDLE,HMODULE,LPSTR,DWORD))
13120 GetProcAddress(nt->hPsApi, "GetModuleFileNameExA");
13121
13122 nt->GetModuleFileNameExW =
13123 (DWORD (__stdcall *)(HANDLE,HMODULE,LPWSTR,DWORD))
13124 GetProcAddress(nt->hPsApi, "GetModuleFileNameExW");
13125
13126 nt->GetProcessImageFileNameA =
13127 (DWORD (__stdcall *)(HANDLE,LPSTR,DWORD))
13128 GetProcAddress(nt->hPsApi, "GetProcessImageFileNameA");
13129
13130 nt->GetProcessImageFileNameW =
13131 (DWORD (__stdcall *)(HANDLE,LPWSTR,DWORD))
13132 GetProcAddress(nt->hPsApi, "GetProcessImageFileNameW");
13133 }
13134
13135 // Registry related API
13136 nt->RegDeleteKeyExA =
13137 (LONG (__stdcall *)(HKEY,LPCTSTR,REGSAM,DWORD))
13138 GetProcAddress(nt->hAdvapi32, "RegDeleteKeyExA");
13139
13140 // Security related API
13141 if (nt->hSecur32 != NULL)
13142 {
13143 nt->GetUserNameExA =
13144 (BOOL (__stdcall *)(EXTENDED_NAME_FORMAT,LPSTR,PULONG))
13145 GetProcAddress(nt->hSecur32, "GetUserNameExA");
13146
13147 nt->GetUserNameExW =
13148 (BOOL (__stdcall *)(EXTENDED_NAME_FORMAT,LPWSTR,PULONG))
13149 GetProcAddress(nt->hSecur32, "GetUserNameExW");
13150
13151 nt->LsaConnectUntrusted =
13152 (NTSTATUS (__stdcall *)(PHANDLE))
13153 GetProcAddress(nt->hSecur32, "LsaConnectUntrusted");
13154
13155 nt->LsaLookupAuthenticationPackage =
13156 (NTSTATUS (__stdcall *)(HANDLE,PLSA_STRING,PULONG))
13157 GetProcAddress(nt->hSecur32, "LsaLookupAuthenticationPackage");
13158
13159 nt->LsaLogonUser =
13160 (NTSTATUS (__stdcall *)(HANDLE,PLSA_STRING,SECURITY_LOGON_TYPE,ULONG,PVOID,ULONG,PTOKEN_GROUPS,PTOKEN_SOURCE,PVOID,PULONG,PLUID,PHANDLE,PQUOTA_LIMITS,PNTSTATUS))
13161 GetProcAddress(nt->hSecur32, "LsaLogonUser");
13162
13163 nt->LsaDeregisterLogonProcess =
13164 (NTSTATUS (__stdcall *)(HANDLE))
13165 GetProcAddress(nt->hSecur32, "LsaDeregisterLogonProcess");
13166
13167 nt->LsaFreeReturnBuffer =
13168 (NTSTATUS (__stdcall *)(PVOID))
13169 GetProcAddress(nt->hSecur32, "LsaFreeReturnBuffer");
13170 }
13171
13172 // WCM related API of Windows 8
13173 if (nt->hWcmapi != NULL)
13174 {
13175 nt->WcmQueryProperty =
13176 (DWORD (__stdcall *)(const GUID *,LPCWSTR,MS_WCM_PROPERTY,PVOID,PDWORD,PBYTE *))
13177 GetProcAddress(nt->hWcmapi, "WcmQueryProperty");
13178
13179 nt->WcmSetProperty =
13180 (DWORD (__stdcall *)(const GUID *,LPCWSTR,MS_WCM_PROPERTY,PVOID,DWORD,const BYTE *))
13181 GetProcAddress(nt->hWcmapi, "WcmSetProperty");
13182
13183 nt->WcmFreeMemory =
13184 (void (__stdcall *)(PVOID))
13185 GetProcAddress(nt->hWcmapi, "WcmFreeMemory");
13186
13187 nt->WcmGetProfileList =
13188 (DWORD (__stdcall *)(PVOID,MS_WCM_PROFILE_INFO_LIST **))
13189 GetProcAddress(nt->hWcmapi, "WcmGetProfileList");
13190 }
13191
13192 nt->AllocateLocallyUniqueId =
13193 (BOOL (__stdcall *)(PLUID))
13194 GetProcAddress(nt->hAdvapi32, "AllocateLocallyUniqueId");
13195
13196 // Desktop related API
13197 if (nt->hUser32 != NULL)
13198 {
13199 nt->SwitchDesktop =
13200 (BOOL (__stdcall *)(HDESK))
13201 GetProcAddress(nt->hUser32, "SwitchDesktop");
13202 nt->OpenDesktopA =
13203 (HDESK (__stdcall *)(LPTSTR,DWORD,BOOL,ACCESS_MASK))
13204 GetProcAddress(nt->hUser32, "OpenDesktopA");
13205 nt->CloseDesktop =
13206 (BOOL (__stdcall *)(HDESK))
13207 GetProcAddress(nt->hUser32, "CloseDesktop");
13208 }
13209
13210 // DWM API
13211 if (nt->hDwmapi)
13212 {
13213 nt->DwmIsCompositionEnabled =
13214 (HRESULT (__stdcall *)(BOOL *))
13215 GetProcAddress(nt->hDwmapi, "DwmIsCompositionEnabled");
13216 }
13217
13218 // Debug related API
13219 if (nt->hDbgHelp != NULL)
13220 {
13221 nt->MiniDumpWriteDump =
13222 (BOOL (__stdcall *)(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,PMINIDUMP_EXCEPTION_INFORMATION,PMINIDUMP_USER_STREAM_INFORMATION,PMINIDUMP_CALLBACK_INFORMATION))
13223 GetProcAddress(nt->hDbgHelp, "MiniDumpWriteDump");
13224 }
13225
13226 return nt;
13227 }
13228
13229 // Release of NT system function
MsFreeNtApiFunctions(NT_API * nt)13230 void MsFreeNtApiFunctions(NT_API *nt)
13231 {
13232 // Validate arguments
13233 if (nt == NULL)
13234 {
13235 return;
13236 }
13237
13238 if (nt->hSecur32 != NULL)
13239 {
13240 FreeLibrary(nt->hSecur32);
13241 }
13242
13243 if (nt->hNewDev != NULL)
13244 {
13245 FreeLibrary(nt->hSetupApi);
13246 FreeLibrary(nt->hNewDev);
13247 }
13248
13249 FreeLibrary(nt->hAdvapi32);
13250
13251 FreeLibrary(nt->hShell32);
13252
13253 if (nt->hWtsApi32 != NULL)
13254 {
13255 FreeLibrary(nt->hWtsApi32);
13256 }
13257
13258 if (nt->hPsApi != NULL)
13259 {
13260 FreeLibrary(nt->hPsApi);
13261 }
13262
13263 if (nt->hUser32 != NULL)
13264 {
13265 FreeLibrary(nt->hUser32);
13266 }
13267
13268 if (nt->hDbgHelp != NULL)
13269 {
13270 FreeLibrary(nt->hDbgHelp);
13271 }
13272
13273 if (nt->hWcmapi != NULL)
13274 {
13275 FreeLibrary(nt->hWcmapi);
13276 }
13277
13278 if (nt->hDwmapi != NULL)
13279 {
13280 FreeLibrary(nt->hDwmapi);
13281 }
13282
13283 FreeLibrary(nt->hKernel32);
13284
13285 Free(nt);
13286 }
13287
13288 // Get whether the screen color is like to Aero of Windows Vista or later
MsIsAeroColor()13289 bool MsIsAeroColor()
13290 {
13291 UINT r;
13292 if (MsIsNt() == false)
13293 {
13294 return false;
13295 }
13296
13297 if (MsIsVista() == false)
13298 {
13299 return false;
13300 }
13301
13302 r = GetSysColor(COLOR_MENU);
13303 if (r == 0xFFFFFF || r == 0xF0F0F0 || r >= 0xF00000)
13304 {
13305 return true;
13306 }
13307
13308 if (MsIsAeroEnabled())
13309 {
13310 return true;
13311 }
13312
13313 return false;
13314 }
13315
13316 // Get whether Aero is enabled
MsIsAeroEnabled()13317 bool MsIsAeroEnabled()
13318 {
13319 bool ret;
13320 if (MsIsNt() == false)
13321 {
13322 return false;
13323 }
13324
13325 if (ms->nt->DwmIsCompositionEnabled == NULL)
13326 {
13327 return false;
13328 }
13329
13330 ret = false;
13331
13332 if (ms->nt->DwmIsCompositionEnabled(&ret) != S_OK)
13333 {
13334 return false;
13335 }
13336
13337 return ret;
13338 }
13339
13340 // Generate an access mask to force accessing to the 32 bit registry key for 64 bit application
MsRegAccessMaskFor64Bit(bool force32bit)13341 DWORD MsRegAccessMaskFor64Bit(bool force32bit)
13342 {
13343 return MsRegAccessMaskFor64BitEx(force32bit, false);
13344 }
MsRegAccessMaskFor64BitEx(bool force32bit,bool force64bit)13345 DWORD MsRegAccessMaskFor64BitEx(bool force32bit, bool force64bit)
13346 {
13347 if (MsIs64BitWindows() == false)
13348 {
13349 return 0;
13350 }
13351 if (force32bit)
13352 {
13353 return KEY_WOW64_32KEY;
13354 }
13355 if (force64bit)
13356 {
13357 return KEY_WOW64_64KEY;
13358 }
13359
13360 return 0;
13361 }
13362
13363 // Load the hive
MsRegLoadHive(UINT root,wchar_t * keyname,wchar_t * filename)13364 bool MsRegLoadHive(UINT root, wchar_t *keyname, wchar_t *filename)
13365 {
13366 LONG ret;
13367 if (keyname == NULL || filename == NULL)
13368 {
13369 WHERE;
13370 return false;
13371 }
13372
13373 if (ms->nt == NULL || ms->nt->RegLoadKeyW == NULL || ms->nt->RegUnLoadKeyW == NULL)
13374 {
13375 WHERE;
13376 return false;
13377 }
13378
13379 ret = ms->nt->RegLoadKeyW(MsGetRootKeyFromInt(root), keyname, filename);
13380
13381 if (ret != ERROR_SUCCESS)
13382 {
13383 Debug("RegLoadKeyW: %S %S %u\n", keyname, filename, GetLastError());
13384 return false;
13385 }
13386 WHERE;
13387
13388 return true;
13389 }
13390
13391 // Unload the hive
MsRegUnloadHive(UINT root,wchar_t * keyname)13392 bool MsRegUnloadHive(UINT root, wchar_t *keyname)
13393 {
13394 LONG ret;
13395 if (keyname == NULL)
13396 {
13397 return false;
13398 }
13399
13400 if (ms->nt == NULL || ms->nt->RegLoadKeyW == NULL || ms->nt->RegUnLoadKeyW == NULL)
13401 {
13402 return false;
13403 }
13404
13405 ret = ms->nt->RegUnLoadKeyW(MsGetRootKeyFromInt(root), keyname);
13406
13407 if (ret != ERROR_SUCCESS)
13408 {
13409 Debug("RegUnLoadKeyW: %u\n", GetLastError());
13410 return false;
13411 }
13412
13413 return true;
13414 }
13415
13416 // Delete the value
MsRegDeleteValue(UINT root,char * keyname,char * valuename)13417 bool MsRegDeleteValue(UINT root, char *keyname, char *valuename)
13418 {
13419 return MsRegDeleteValueEx(root, keyname, valuename, false);
13420 }
MsRegDeleteValueEx(UINT root,char * keyname,char * valuename,bool force32bit)13421 bool MsRegDeleteValueEx(UINT root, char *keyname, char *valuename, bool force32bit)
13422 {
13423 return MsRegDeleteValueEx2(root, keyname, valuename, force32bit, false);
13424 }
MsRegDeleteValueEx2(UINT root,char * keyname,char * valuename,bool force32bit,bool force64bit)13425 bool MsRegDeleteValueEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
13426 {
13427 HKEY h;
13428 bool ret;
13429 // Validate arguments
13430 if (keyname == NULL)
13431 {
13432 return false;
13433 }
13434
13435 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
13436 {
13437 return false;
13438 }
13439
13440 if (RegDeleteValue(h, valuename) != ERROR_SUCCESS)
13441 {
13442 ret = false;
13443 }
13444 else
13445 {
13446 ret = true;
13447 }
13448
13449 RegCloseKey(h);
13450
13451 return ret;
13452 }
13453
13454 // Delete the key
MsRegDeleteKey(UINT root,char * keyname)13455 bool MsRegDeleteKey(UINT root, char *keyname)
13456 {
13457 return MsRegDeleteKeyEx(root, keyname, false);
13458 }
MsRegDeleteKeyEx(UINT root,char * keyname,bool force32bit)13459 bool MsRegDeleteKeyEx(UINT root, char *keyname, bool force32bit)
13460 {
13461 return MsRegDeleteKeyEx2(root, keyname, force32bit, false);
13462 }
MsRegDeleteKeyEx2(UINT root,char * keyname,bool force32bit,bool force64bit)13463 bool MsRegDeleteKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)
13464 {
13465 // Validate arguments
13466 if (keyname == NULL)
13467 {
13468 return false;
13469 }
13470
13471 if (MsIsNt() && ms->nt->RegDeleteKeyExA != NULL)
13472 {
13473 if (ms->nt->RegDeleteKeyExA(MsGetRootKeyFromInt(root), keyname, MsRegAccessMaskFor64BitEx(force32bit, force64bit), 0) != ERROR_SUCCESS)
13474 {
13475 return false;
13476 }
13477 }
13478 else
13479 {
13480 if (RegDeleteKey(MsGetRootKeyFromInt(root), keyname) != ERROR_SUCCESS)
13481 {
13482 return false;
13483 }
13484 }
13485
13486 return true;
13487 }
13488
13489 // Enumeration of values
MsRegEnumValue(UINT root,char * keyname)13490 TOKEN_LIST *MsRegEnumValue(UINT root, char *keyname)
13491 {
13492 return MsRegEnumValueEx(root, keyname, false);
13493 }
MsRegEnumValueEx(UINT root,char * keyname,bool force32bit)13494 TOKEN_LIST *MsRegEnumValueEx(UINT root, char *keyname, bool force32bit)
13495 {
13496 return MsRegEnumValueEx2(root, keyname, force32bit, false);
13497 }
MsRegEnumValueEx2(UINT root,char * keyname,bool force32bit,bool force64bit)13498 TOKEN_LIST *MsRegEnumValueEx2(UINT root, char *keyname, bool force32bit, bool force64bit)
13499 {
13500 HKEY h;
13501 UINT i;
13502 TOKEN_LIST *t;
13503 LIST *o;
13504
13505 if (keyname == NULL)
13506 {
13507 h = MsGetRootKeyFromInt(root);
13508 }
13509 else
13510 {
13511 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
13512 {
13513 return NULL;
13514 }
13515 }
13516
13517 o = NewListFast(CompareStr);
13518
13519 for (i = 0;;i++)
13520 {
13521 char tmp[MAX_SIZE];
13522 UINT ret;
13523 UINT size = sizeof(tmp);
13524
13525 Zero(tmp, sizeof(tmp));
13526 ret = RegEnumValue(h, i, tmp, &size, NULL, NULL, NULL, NULL);
13527 if (ret == ERROR_NO_MORE_ITEMS)
13528 {
13529 break;
13530 }
13531 else if (ret != ERROR_SUCCESS)
13532 {
13533 break;
13534 }
13535
13536 Add(o, CopyStr(tmp));
13537 }
13538
13539 Sort(o);
13540
13541 t = ZeroMalloc(sizeof(TOKEN_LIST));
13542 t->NumTokens = LIST_NUM(o);
13543 t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
13544 for (i = 0;i < t->NumTokens;i++)
13545 {
13546 t->Token[i] = LIST_DATA(o, i);
13547 }
13548
13549 ReleaseList(o);
13550
13551 if (keyname != NULL)
13552 {
13553 RegCloseKey(h);
13554 }
13555
13556 return t;
13557 }
13558
13559 // Enumeration of the keys
MsRegEnumKey(UINT root,char * keyname)13560 TOKEN_LIST *MsRegEnumKey(UINT root, char *keyname)
13561 {
13562 return MsRegEnumKeyEx(root, keyname, false);
13563 }
MsRegEnumKeyEx(UINT root,char * keyname,bool force32bit)13564 TOKEN_LIST *MsRegEnumKeyEx(UINT root, char *keyname, bool force32bit)
13565 {
13566 return MsRegEnumKeyEx2(root, keyname, force32bit, false);
13567 }
MsRegEnumKeyEx2(UINT root,char * keyname,bool force32bit,bool force64bit)13568 TOKEN_LIST *MsRegEnumKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)
13569 {
13570 HKEY h;
13571 UINT i;
13572 TOKEN_LIST *t;
13573 LIST *o;
13574
13575 if (keyname == NULL)
13576 {
13577 h = MsGetRootKeyFromInt(root);
13578 }
13579 else
13580 {
13581 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
13582 {
13583 return NULL;
13584 }
13585 }
13586
13587 o = NewListFast(CompareStr);
13588
13589 for (i = 0;;i++)
13590 {
13591 char tmp[MAX_SIZE];
13592 UINT ret;
13593 UINT size = sizeof(tmp);
13594 FILETIME ft;
13595
13596 Zero(tmp, sizeof(tmp));
13597 ret = RegEnumKeyEx(h, i, tmp, &size, NULL, NULL, NULL, &ft);
13598 if (ret == ERROR_NO_MORE_ITEMS)
13599 {
13600 break;
13601 }
13602 else if (ret != ERROR_SUCCESS)
13603 {
13604 break;
13605 }
13606
13607 Add(o, CopyStr(tmp));
13608 }
13609
13610 Sort(o);
13611
13612 t = ZeroMalloc(sizeof(TOKEN_LIST));
13613 t->NumTokens = LIST_NUM(o);
13614 t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
13615 for (i = 0;i < t->NumTokens;i++)
13616 {
13617 t->Token[i] = LIST_DATA(o, i);
13618 }
13619
13620 ReleaseList(o);
13621
13622 if (keyname != NULL)
13623 {
13624 RegCloseKey(h);
13625 }
13626
13627 return t;
13628 }
13629
13630 // Set the binary data
MsRegWriteBin(UINT root,char * keyname,char * valuename,void * data,UINT size)13631 bool MsRegWriteBin(UINT root, char *keyname, char *valuename, void *data, UINT size)
13632 {
13633 return MsRegWriteBinEx(root, keyname, valuename, data, size, false);
13634 }
MsRegWriteBinEx(UINT root,char * keyname,char * valuename,void * data,UINT size,bool force32bit)13635 bool MsRegWriteBinEx(UINT root, char *keyname, char *valuename, void *data, UINT size, bool force32bit)
13636 {
13637 return MsRegWriteBinEx2(root, keyname, valuename, data, size, force32bit, false);
13638 }
MsRegWriteBinEx2(UINT root,char * keyname,char * valuename,void * data,UINT size,bool force32bit,bool force64bit)13639 bool MsRegWriteBinEx2(UINT root, char *keyname, char *valuename, void *data, UINT size, bool force32bit, bool force64bit)
13640 {
13641 // Validate arguments
13642 if (keyname == NULL || (size != 0 && data == NULL))
13643 {
13644 return false;
13645 }
13646
13647 return MsRegWriteValueEx2(root, keyname, valuename, REG_BINARY, data, size, force32bit, force64bit);
13648 }
13649
13650 // Set the integer value
MsRegWriteInt(UINT root,char * keyname,char * valuename,UINT value)13651 bool MsRegWriteInt(UINT root, char *keyname, char *valuename, UINT value)
13652 {
13653 return MsRegWriteIntEx(root, keyname, valuename, value, false);
13654 }
MsRegWriteIntEx(UINT root,char * keyname,char * valuename,UINT value,bool force32bit)13655 bool MsRegWriteIntEx(UINT root, char *keyname, char *valuename, UINT value, bool force32bit)
13656 {
13657 return MsRegWriteIntEx2(root, keyname, valuename, value, force32bit, false);
13658 }
MsRegWriteIntEx2(UINT root,char * keyname,char * valuename,UINT value,bool force32bit,bool force64bit)13659 bool MsRegWriteIntEx2(UINT root, char *keyname, char *valuename, UINT value, bool force32bit, bool force64bit)
13660 {
13661 // Validate arguments
13662 if (keyname == NULL)
13663 {
13664 return false;
13665 }
13666
13667 // Endian correction
13668 if (IsBigEndian())
13669 {
13670 value = Swap32(value);
13671 }
13672
13673 return MsRegWriteValueEx2(root, keyname, valuename, REG_DWORD_LITTLE_ENDIAN, &value, sizeof(UINT), force32bit, force64bit);
13674 }
13675
13676 // Set the string
MsRegWriteStrExpand(UINT root,char * keyname,char * valuename,char * str)13677 bool MsRegWriteStrExpand(UINT root, char *keyname, char *valuename, char *str)
13678 {
13679 return MsRegWriteStrExpandEx(root, keyname, valuename, str, false);
13680 }
MsRegWriteStrExpandEx(UINT root,char * keyname,char * valuename,char * str,bool force32bit)13681 bool MsRegWriteStrExpandEx(UINT root, char *keyname, char *valuename, char *str, bool force32bit)
13682 {
13683 return MsRegWriteStrExpandEx2(root, keyname, valuename, str, force32bit, false);
13684 }
MsRegWriteStrExpandEx2(UINT root,char * keyname,char * valuename,char * str,bool force32bit,bool force64bit)13685 bool MsRegWriteStrExpandEx2(UINT root, char *keyname, char *valuename, char *str, bool force32bit, bool force64bit)
13686 {
13687 // Validate arguments
13688 if (keyname == NULL || str == NULL)
13689 {
13690 return false;
13691 }
13692
13693 return MsRegWriteValueEx2(root, keyname, valuename, REG_EXPAND_SZ, str, StrSize(str), force32bit, force64bit);
13694 }
MsRegWriteStrExpandW(UINT root,char * keyname,char * valuename,wchar_t * str)13695 bool MsRegWriteStrExpandW(UINT root, char *keyname, char *valuename, wchar_t *str)
13696 {
13697 return MsRegWriteStrExpandExW(root, keyname, valuename, str, false);
13698 }
MsRegWriteStrExpandExW(UINT root,char * keyname,char * valuename,wchar_t * str,bool force32bit)13699 bool MsRegWriteStrExpandExW(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit)
13700 {
13701 return MsRegWriteStrExpandEx2W(root, keyname, valuename, str, force32bit, false);
13702 }
MsRegWriteStrExpandEx2W(UINT root,char * keyname,char * valuename,wchar_t * str,bool force32bit,bool force64bit)13703 bool MsRegWriteStrExpandEx2W(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit, bool force64bit)
13704 {
13705 // Validate arguments
13706 if (keyname == NULL || str == NULL)
13707 {
13708 return false;
13709 }
13710
13711 return MsRegWriteValueEx2W(root, keyname, valuename, REG_EXPAND_SZ, str, UniStrSize(str), force32bit, force64bit);
13712 }
13713
MsRegWriteStr(UINT root,char * keyname,char * valuename,char * str)13714 bool MsRegWriteStr(UINT root, char *keyname, char *valuename, char *str)
13715 {
13716 return MsRegWriteStrEx(root, keyname, valuename, str, false);
13717 }
MsRegWriteStrEx(UINT root,char * keyname,char * valuename,char * str,bool force32bit)13718 bool MsRegWriteStrEx(UINT root, char *keyname, char *valuename, char *str, bool force32bit)
13719 {
13720 return MsRegWriteStrEx2(root, keyname, valuename, str, force32bit, false);
13721 }
MsRegWriteStrEx2(UINT root,char * keyname,char * valuename,char * str,bool force32bit,bool force64bit)13722 bool MsRegWriteStrEx2(UINT root, char *keyname, char *valuename, char *str, bool force32bit, bool force64bit)
13723 {
13724 // Validate arguments
13725 if (keyname == NULL || str == NULL)
13726 {
13727 return false;
13728 }
13729
13730 return MsRegWriteValueEx2(root, keyname, valuename, REG_SZ, str, StrSize(str), force32bit, force64bit);
13731 }
MsRegWriteStrW(UINT root,char * keyname,char * valuename,wchar_t * str)13732 bool MsRegWriteStrW(UINT root, char *keyname, char *valuename, wchar_t *str)
13733 {
13734 return MsRegWriteStrExW(root, keyname, valuename, str, false);
13735 }
MsRegWriteStrExW(UINT root,char * keyname,char * valuename,wchar_t * str,bool force32bit)13736 bool MsRegWriteStrExW(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit)
13737 {
13738 return MsRegWriteStrEx2W(root, keyname, valuename, str, force32bit, false);
13739 }
MsRegWriteStrEx2W(UINT root,char * keyname,char * valuename,wchar_t * str,bool force32bit,bool force64bit)13740 bool MsRegWriteStrEx2W(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit, bool force64bit)
13741 {
13742 // Validate arguments
13743 if (keyname == NULL || str == NULL)
13744 {
13745 return false;
13746 }
13747
13748 return MsRegWriteValueEx2W(root, keyname, valuename, REG_SZ, str, UniStrSize(str), force32bit, force64bit);
13749 }
13750
13751 // Set the value
MsRegWriteValue(UINT root,char * keyname,char * valuename,UINT type,void * data,UINT size)13752 bool MsRegWriteValue(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size)
13753 {
13754 return MsRegWriteValueEx(root, keyname, valuename, type, data, size, false);
13755 }
MsRegWriteValueEx(UINT root,char * keyname,char * valuename,UINT type,void * data,UINT size,bool force32bit)13756 bool MsRegWriteValueEx(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit)
13757 {
13758 return MsRegWriteValueEx2(root, keyname, valuename, type, data, size, force32bit, false);
13759 }
MsRegWriteValueEx2(UINT root,char * keyname,char * valuename,UINT type,void * data,UINT size,bool force32bit,bool force64bit)13760 bool MsRegWriteValueEx2(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit, bool force64bit)
13761 {
13762 HKEY h;
13763 // Validate arguments
13764 if (keyname == NULL || (size != 0 && data == NULL))
13765 {
13766 return false;
13767 }
13768
13769 // Create a key
13770 MsRegNewKeyEx2(root, keyname, force32bit, force64bit);
13771
13772 // Open the key
13773 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
13774 {
13775 return false;
13776 }
13777
13778 // Write the value
13779 if (RegSetValueEx(h, valuename, 0, type, data, size) != ERROR_SUCCESS)
13780 {
13781 RegCloseKey(h);
13782 return false;
13783 }
13784
13785 // Close the key
13786 RegCloseKey(h);
13787
13788 return true;
13789 }
MsRegWriteValueW(UINT root,char * keyname,char * valuename,UINT type,void * data,UINT size)13790 bool MsRegWriteValueW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size)
13791 {
13792 return MsRegWriteValueExW(root, keyname, valuename, type, data, size, false);
13793 }
MsRegWriteValueExW(UINT root,char * keyname,char * valuename,UINT type,void * data,UINT size,bool force32bit)13794 bool MsRegWriteValueExW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit)
13795 {
13796 return MsRegWriteValueEx2W(root, keyname, valuename, type, data, size, force32bit, false);
13797 }
MsRegWriteValueEx2W(UINT root,char * keyname,char * valuename,UINT type,void * data,UINT size,bool force32bit,bool force64bit)13798 bool MsRegWriteValueEx2W(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit, bool force64bit)
13799 {
13800 HKEY h;
13801 wchar_t *valuename_w;
13802 // Validate arguments
13803 if (keyname == NULL || (size != 0 && data == NULL))
13804 {
13805 return false;
13806 }
13807
13808 if (IsNt() == false)
13809 {
13810 UINT size_a;
13811 void *data_a;
13812 bool ret;
13813
13814 if (type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ)
13815 {
13816 data_a = CopyUniToStr(data);
13817 size_a = StrSize(data_a);
13818 }
13819 else
13820 {
13821 data_a = Clone(data, size);
13822 size_a = size;
13823 }
13824
13825 ret = MsRegWriteValueEx2(root, keyname, valuename, type, data_a, size_a, force32bit, force64bit);
13826
13827 Free(data_a);
13828
13829 return ret;
13830 }
13831
13832 // Create a key
13833 MsRegNewKeyEx2(root, keyname, force32bit, force64bit);
13834
13835 // Open the key
13836 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
13837 {
13838 return false;
13839 }
13840
13841 valuename_w = CopyStrToUni(valuename);
13842
13843 // Write the value
13844 if (RegSetValueExW(h, valuename_w, 0, type, data, size) != ERROR_SUCCESS)
13845 {
13846 RegCloseKey(h);
13847 Free(valuename_w);
13848 return false;
13849 }
13850
13851 // Close the key
13852 RegCloseKey(h);
13853 Free(valuename_w);
13854
13855 return true;
13856 }
13857
13858 // Get the binary data
MsRegReadBin(UINT root,char * keyname,char * valuename)13859 BUF *MsRegReadBin(UINT root, char *keyname, char *valuename)
13860 {
13861 return MsRegReadBinEx(root, keyname, valuename, false);
13862 }
MsRegReadBinEx(UINT root,char * keyname,char * valuename,bool force32bit)13863 BUF *MsRegReadBinEx(UINT root, char *keyname, char *valuename, bool force32bit)
13864 {
13865 return MsRegReadBinEx2(root, keyname, valuename, force32bit, false);
13866 }
MsRegReadBinEx2(UINT root,char * keyname,char * valuename,bool force32bit,bool force64bit)13867 BUF *MsRegReadBinEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
13868 {
13869 char *ret;
13870 UINT type, size;
13871 BUF *b;
13872 // Validate arguments
13873 if (keyname == NULL || valuename == NULL)
13874 {
13875 return 0;
13876 }
13877
13878 // Read the value
13879 if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
13880 {
13881 return 0;
13882 }
13883
13884 b = NewBuf();
13885
13886 WriteBuf(b, ret, size);
13887 SeekBuf(b, 0, 0);
13888
13889 Free(ret);
13890
13891 return b;
13892 }
13893
13894 // Get an integer value
MsRegReadInt(UINT root,char * keyname,char * valuename)13895 UINT MsRegReadInt(UINT root, char *keyname, char *valuename)
13896 {
13897 return MsRegReadIntEx(root, keyname, valuename, false);
13898 }
MsRegReadIntEx(UINT root,char * keyname,char * valuename,bool force32bit)13899 UINT MsRegReadIntEx(UINT root, char *keyname, char *valuename, bool force32bit)
13900 {
13901 return MsRegReadIntEx2(root, keyname, valuename, force32bit, false);
13902 }
MsRegReadIntEx2(UINT root,char * keyname,char * valuename,bool force32bit,bool force64bit)13903 UINT MsRegReadIntEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
13904 {
13905 char *ret;
13906 UINT type, size;
13907 UINT value;
13908 // Validate arguments
13909 if (keyname == NULL || valuename == NULL)
13910 {
13911 return 0;
13912 }
13913
13914 // Read the value
13915 if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
13916 {
13917 return 0;
13918 }
13919
13920 // Check the type
13921 if (type != REG_DWORD_LITTLE_ENDIAN && type != REG_DWORD_BIG_ENDIAN)
13922 {
13923 // It is not a DWORD
13924 Free(ret);
13925 return 0;
13926 }
13927
13928 // Check the size
13929 if (size != sizeof(UINT))
13930 {
13931 Free(ret);
13932 return 0;
13933 }
13934
13935 Copy(&value, ret, sizeof(UINT));
13936
13937 Free(ret);
13938
13939 // Endian conversion
13940 if (IsLittleEndian())
13941 {
13942 #ifdef REG_DWORD_BIG_ENDIAN
13943 if (type == REG_DWORD_BIG_ENDIAN)
13944 {
13945 value = Swap32(value);
13946 }
13947 #endif // REG_DWORD_BIG_ENDIAN
13948 }
13949 else
13950 {
13951 #ifdef REG_DWORD_LITTLE_ENDIAN_FLAG
13952 if (type == REG_DWORD_LITTLE_ENDIAN_FLAG)
13953 {
13954 value = Swap32(value);
13955 }
13956 #endif // REG_DWORD_LITTLE_ENDIAN_FLAG
13957 }
13958
13959 return value;
13960 }
13961
13962 // Get a string list
MsRegReadStrList(UINT root,char * keyname,char * valuename)13963 LIST *MsRegReadStrList(UINT root, char *keyname, char *valuename)
13964 {
13965 return MsRegReadStrListEx(root, keyname, valuename, false);
13966 }
MsRegReadStrListEx(UINT root,char * keyname,char * valuename,bool force32bit)13967 LIST *MsRegReadStrListEx(UINT root, char *keyname, char *valuename, bool force32bit)
13968 {
13969 return MsRegReadStrListEx2(root, keyname, valuename, force32bit, false);
13970 }
MsRegReadStrListEx2(UINT root,char * keyname,char * valuename,bool force32bit,bool force64bit)13971 LIST *MsRegReadStrListEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
13972 {
13973 LIST *o;
13974 char *ret;
13975 UINT type, size;
13976 // Validate arguments
13977 if (keyname == NULL || valuename == NULL)
13978 {
13979 return NULL;
13980 }
13981
13982 // Read the value
13983 if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
13984 {
13985 return NULL;
13986 }
13987
13988 // Check the type
13989 if (type != REG_MULTI_SZ)
13990 {
13991 // It is not a string list
13992 Free(ret);
13993 return NULL;
13994 }
13995
13996 if (size < 2)
13997 {
13998 // Invalid size
13999 Free(ret);
14000 return NULL;
14001 }
14002
14003 if (ret[size - 1] != 0)
14004 {
14005 // Invalid data
14006 Free(ret);
14007 return NULL;
14008 }
14009
14010 // Creating a list
14011 o = StrToStrList(ret, size);
14012
14013 Free(ret);
14014
14015 return o;
14016 }
14017
14018 // Get a string
MsRegReadStr(UINT root,char * keyname,char * valuename)14019 char *MsRegReadStr(UINT root, char *keyname, char *valuename)
14020 {
14021 return MsRegReadStrEx(root, keyname, valuename, false);
14022 }
MsRegReadStrEx(UINT root,char * keyname,char * valuename,bool force32bit)14023 char *MsRegReadStrEx(UINT root, char *keyname, char *valuename, bool force32bit)
14024 {
14025 return MsRegReadStrEx2(root, keyname, valuename, force32bit, false);
14026 }
MsRegReadStrEx2(UINT root,char * keyname,char * valuename,bool force32bit,bool force64bit)14027 char *MsRegReadStrEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
14028 {
14029 char *ret;
14030 UINT type, size;
14031 // Validate arguments
14032 if (keyname == NULL || valuename == NULL)
14033 {
14034 return NULL;
14035 }
14036
14037 // Read the value
14038 if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
14039 {
14040 return NULL;
14041 }
14042
14043 // Check the type
14044 if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ)
14045 {
14046 // It is not a string
14047 Free(ret);
14048
14049 if (type == REG_MULTI_SZ)
14050 {
14051 // It is a string list
14052 LIST *o = MsRegReadStrList(root, keyname, valuename);
14053 if (o != NULL)
14054 {
14055 if (LIST_NUM(o) >= 1)
14056 {
14057 ret = CopyStr(LIST_DATA(o, 0));
14058 FreeStrList(o);
14059 return ret;
14060 }
14061 }
14062 }
14063 return NULL;
14064 }
14065
14066 if (size == 0)
14067 {
14068 // Invalid size
14069 Free(ret);
14070
14071 return CopyStr("");
14072 }
14073
14074 if (ret[size - 1] != 0)
14075 {
14076 // Invalid data
14077 Free(ret);
14078 return NULL;
14079 }
14080
14081 return ret;
14082 }
MsRegReadStrW(UINT root,char * keyname,char * valuename)14083 wchar_t *MsRegReadStrW(UINT root, char *keyname, char *valuename)
14084 {
14085 return MsRegReadStrExW(root, keyname, valuename, false);
14086 }
MsRegReadStrExW(UINT root,char * keyname,char * valuename,bool force32bit)14087 wchar_t *MsRegReadStrExW(UINT root, char *keyname, char *valuename, bool force32bit)
14088 {
14089 return MsRegReadStrEx2W(root, keyname, valuename, force32bit, false);
14090 }
MsRegReadStrEx2W(UINT root,char * keyname,char * valuename,bool force32bit,bool force64bit)14091 wchar_t *MsRegReadStrEx2W(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
14092 {
14093 wchar_t *ret;
14094 UINT type, size;
14095 // Validate arguments
14096 if (keyname == NULL || valuename == NULL)
14097 {
14098 return NULL;
14099 }
14100
14101 // Read the value
14102 if (MsRegReadValueEx2W(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
14103 {
14104 return NULL;
14105 }
14106
14107 // Check the type
14108 if (type != REG_SZ && type != REG_EXPAND_SZ)
14109 {
14110 // It is not a string
14111 Free(ret);
14112
14113 return NULL;
14114 }
14115
14116 if (ret[size / sizeof(wchar_t) - 1] != 0)
14117 {
14118 // Invalid data
14119 Free(ret);
14120 return NULL;
14121 }
14122
14123 return ret;
14124 }
14125
14126 // Read the value
MsRegReadValue(UINT root,char * keyname,char * valuename,void ** data,UINT * type,UINT * size)14127 bool MsRegReadValue(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size)
14128 {
14129 return MsRegReadValueEx(root, keyname, valuename, data, type, size, false);
14130 }
MsRegReadValueEx(UINT root,char * keyname,char * valuename,void ** data,UINT * type,UINT * size,bool force32bit)14131 bool MsRegReadValueEx(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit)
14132 {
14133 return MsRegReadValueEx2(root, keyname, valuename, data, type, size, force32bit, false);
14134 }
MsRegReadValueEx2(UINT root,char * keyname,char * valuename,void ** data,UINT * type,UINT * size,bool force32bit,bool force64bit)14135 bool MsRegReadValueEx2(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit)
14136 {
14137 HKEY h;
14138 UINT ret;
14139 // Validate arguments
14140 if (keyname == NULL || data == NULL || type == NULL || size == NULL)
14141 {
14142 return false;
14143 }
14144 *type = 0;
14145 *size = 0;
14146
14147 // Open the key
14148 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
14149 {
14150 return false;
14151 }
14152
14153 // Open up the value
14154 *data = ZeroMalloc(*size);
14155 ret = RegQueryValueEx(h, valuename, 0, type, *data, size);
14156
14157 if (ret == ERROR_SUCCESS)
14158 {
14159 // Reading is complete
14160 RegCloseKey(h);
14161 return true;
14162 }
14163
14164 if (ret != ERROR_MORE_DATA)
14165 {
14166 // Strange error occurs
14167 Free(*data);
14168 *data = NULL;
14169 RegCloseKey(h);
14170 return false;
14171 }
14172
14173 // Get the data by re-allocating memory
14174 *data = ReAlloc(*data, *size);
14175 ret = RegQueryValueEx(h, valuename, 0, type, *data, size);
14176 if (ret != ERROR_SUCCESS)
14177 {
14178 // An error has occured
14179 Free(*data);
14180 *data = NULL;
14181 RegCloseKey(h);
14182 }
14183
14184 RegCloseKey(h);
14185
14186 return true;
14187 }
MsRegReadValueW(UINT root,char * keyname,char * valuename,void ** data,UINT * type,UINT * size)14188 bool MsRegReadValueW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size)
14189 {
14190 return MsRegReadValueExW(root, keyname, valuename, data, type, size, false);
14191 }
MsRegReadValueExW(UINT root,char * keyname,char * valuename,void ** data,UINT * type,UINT * size,bool force32bit)14192 bool MsRegReadValueExW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit)
14193 {
14194 return MsRegReadValueEx2W(root, keyname, valuename, data, type, size, force32bit, false);
14195 }
MsRegReadValueEx2W(UINT root,char * keyname,char * valuename,void ** data,UINT * type,UINT * size,bool force32bit,bool force64bit)14196 bool MsRegReadValueEx2W(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit)
14197 {
14198 HKEY h;
14199 UINT ret;
14200 wchar_t *valuename_w;
14201 // Validate arguments
14202 if (keyname == NULL || data == NULL || type == NULL || size == NULL)
14203 {
14204 return false;
14205 }
14206 *type = 0;
14207 *size = 0;
14208
14209 if (IsNt() == false)
14210 {
14211 bool ret;
14212 void *data_a = NULL;
14213 UINT type_a = 0, size_a = 0;
14214
14215 ret = MsRegReadValueEx2(root, keyname, valuename, &data_a, &type_a, &size_a, force32bit, force64bit);
14216
14217 if (ret != false)
14218 {
14219 if (type_a == REG_SZ || type_a == REG_MULTI_SZ || type_a == REG_EXPAND_SZ)
14220 {
14221 *data = CopyStrToUni(data_a);
14222 Free(data_a);
14223
14224 size_a = UniStrSize(*data);
14225 }
14226 else
14227 {
14228 *data = data_a;
14229 }
14230
14231 *type = type_a;
14232 *size = size_a;
14233 }
14234
14235 return ret;
14236 }
14237
14238 // Open the key
14239 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
14240 {
14241 return false;
14242 }
14243
14244 valuename_w = CopyStrToUni(valuename);
14245
14246 // Open up the value
14247 *data = ZeroMalloc(*size);
14248 ret = RegQueryValueExW(h, valuename_w, 0, type, *data, size);
14249
14250 if (ret == ERROR_SUCCESS)
14251 {
14252 // Reading is complete
14253 RegCloseKey(h);
14254 Free(valuename_w);
14255 return true;
14256 }
14257
14258 if (ret != ERROR_MORE_DATA)
14259 {
14260 // Strange error occurs
14261 Free(*data);
14262 *data = NULL;
14263 Free(valuename_w);
14264 RegCloseKey(h);
14265 return false;
14266 }
14267
14268 // Get the data by re-allocating memory
14269 *data = ReAlloc(*data, *size);
14270 ret = RegQueryValueExW(h, valuename_w, 0, type, *data, size);
14271 if (ret != ERROR_SUCCESS)
14272 {
14273 // An error has occured
14274 Free(*data);
14275 *data = NULL;
14276 Free(valuename_w);
14277 RegCloseKey(h);
14278 }
14279
14280 Free(valuename_w);
14281
14282 RegCloseKey(h);
14283
14284 return true;
14285 }
14286
14287 // Get the size and type of value
MsRegGetValueTypeAndSize(UINT root,char * keyname,char * valuename,UINT * type,UINT * size)14288 bool MsRegGetValueTypeAndSize(UINT root, char *keyname, char *valuename, UINT *type, UINT *size)
14289 {
14290 return MsRegGetValueTypeAndSizeEx(root, keyname, valuename, type, size, false);
14291 }
MsRegGetValueTypeAndSizeEx(UINT root,char * keyname,char * valuename,UINT * type,UINT * size,bool force32bit)14292 bool MsRegGetValueTypeAndSizeEx(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit)
14293 {
14294 return MsRegGetValueTypeAndSizeEx2(root, keyname, valuename, type, size, force32bit, false);
14295 }
MsRegGetValueTypeAndSizeEx2(UINT root,char * keyname,char * valuename,UINT * type,UINT * size,bool force32bit,bool force64bit)14296 bool MsRegGetValueTypeAndSizeEx2(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit)
14297 {
14298 HKEY h;
14299 UINT ret;
14300 // Validate arguments
14301 if (keyname == NULL)
14302 {
14303 return false;
14304 }
14305 if (type != NULL)
14306 {
14307 *type = 0;
14308 }
14309 if (size != NULL)
14310 {
14311 *size = 0;
14312 }
14313
14314 // Open the key
14315 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
14316 {
14317 return false;
14318 }
14319
14320 // Open up the value
14321 ret = RegQueryValueEx(h, valuename, 0, type, NULL, size);
14322
14323 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
14324 {
14325 RegCloseKey(h);
14326 return true;
14327 }
14328
14329 RegCloseKey(h);
14330
14331 return false;
14332 }
MsRegGetValueTypeAndSizeW(UINT root,char * keyname,char * valuename,UINT * type,UINT * size)14333 bool MsRegGetValueTypeAndSizeW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size)
14334 {
14335 return MsRegGetValueTypeAndSizeExW(root, keyname, valuename, type, size, false);
14336 }
MsRegGetValueTypeAndSizeExW(UINT root,char * keyname,char * valuename,UINT * type,UINT * size,bool force32bit)14337 bool MsRegGetValueTypeAndSizeExW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit)
14338 {
14339 return MsRegGetValueTypeAndSizeEx2W(root, keyname, valuename, type, size, force32bit, false);
14340 }
MsRegGetValueTypeAndSizeEx2W(UINT root,char * keyname,char * valuename,UINT * type,UINT * size,bool force32bit,bool force64bit)14341 bool MsRegGetValueTypeAndSizeEx2W(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit)
14342 {
14343 HKEY h;
14344 UINT ret;
14345 wchar_t *valuename_w;
14346 // Validate arguments
14347 if (keyname == NULL)
14348 {
14349 return false;
14350 }
14351 if (type != NULL)
14352 {
14353 *type = 0;
14354 }
14355 if (size != NULL)
14356 {
14357 *size = 0;
14358 }
14359 if (IsNt() == false)
14360 {
14361 UINT type_a = 0;
14362 UINT size_a = 0;
14363
14364 bool ret = MsRegGetValueTypeAndSizeEx2(root, keyname, valuename, &type_a, &size_a, force32bit, force64bit);
14365
14366 if (type_a == REG_SZ || type_a == REG_MULTI_SZ || type_a == REG_EXPAND_SZ)
14367 {
14368 size_a = size_a * sizeof(wchar_t);
14369 }
14370
14371 if (type != NULL)
14372 {
14373 *type = type_a;
14374 }
14375
14376 if (size != NULL)
14377 {
14378 *size = size_a;
14379 }
14380
14381 return ret;
14382 }
14383
14384 // Open the key
14385 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
14386 {
14387 return false;
14388 }
14389
14390 valuename_w = CopyStrToUni(valuename);
14391
14392 // Open up the value
14393 ret = RegQueryValueExW(h, valuename_w, 0, type, NULL, size);
14394
14395 Free(valuename_w);
14396
14397 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
14398 {
14399 RegCloseKey(h);
14400 return true;
14401 }
14402
14403 RegCloseKey(h);
14404
14405 return false;
14406 }
14407
14408 // Confirm that the specified value exists on the registry
MsRegIsValue(UINT root,char * keyname,char * valuename)14409 bool MsRegIsValue(UINT root, char *keyname, char *valuename)
14410 {
14411 return MsRegIsValueEx(root, keyname, valuename, false);
14412 }
MsRegIsValueEx(UINT root,char * keyname,char * valuename,bool force32bit)14413 bool MsRegIsValueEx(UINT root, char *keyname, char *valuename, bool force32bit)
14414 {
14415 return MsRegIsValueEx2(root, keyname, valuename, force32bit, false);
14416 }
MsRegIsValueEx2(UINT root,char * keyname,char * valuename,bool force32bit,bool force64bit)14417 bool MsRegIsValueEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
14418 {
14419 HKEY h;
14420 UINT type, size;
14421 UINT ret;
14422 // Validate arguments
14423 if (keyname == NULL)
14424 {
14425 return false;
14426 }
14427
14428 // Open the key
14429 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
14430 {
14431 return false;
14432 }
14433
14434 // Open up the value
14435 size = 0;
14436 ret = RegQueryValueEx(h, valuename, 0, &type, NULL, &size);
14437
14438 if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
14439 {
14440 RegCloseKey(h);
14441 return true;
14442 }
14443
14444 RegCloseKey(h);
14445
14446 return false;
14447 }
14448
14449 // Create a key in the registry
MsRegNewKey(UINT root,char * keyname)14450 bool MsRegNewKey(UINT root, char *keyname)
14451 {
14452 return MsRegNewKeyEx(root, keyname, false);
14453 }
MsRegNewKeyEx(UINT root,char * keyname,bool force32bit)14454 bool MsRegNewKeyEx(UINT root, char *keyname, bool force32bit)
14455 {
14456 return MsRegNewKeyEx2(root, keyname, force32bit, false);
14457 }
MsRegNewKeyEx2(UINT root,char * keyname,bool force32bit,bool force64bit)14458 bool MsRegNewKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)
14459 {
14460 HKEY h;
14461 // Validate arguments
14462 if (keyname == NULL)
14463 {
14464 return false;
14465 }
14466
14467 // Confirm whether there is the key
14468 if (MsRegIsKeyEx2(root, keyname, force32bit, force64bit))
14469 {
14470 // Already exists
14471 return true;
14472 }
14473
14474 // Create a key
14475 if (RegCreateKeyEx(MsGetRootKeyFromInt(root), keyname, 0, NULL, REG_OPTION_NON_VOLATILE,
14476 KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), NULL, &h, NULL) != ERROR_SUCCESS)
14477 {
14478 // Failed
14479 return false;
14480 }
14481
14482 RegCloseKey(h);
14483
14484 return true;
14485 }
14486
14487 // Confirm the specified key exists on the registry
MsRegIsKey(UINT root,char * name)14488 bool MsRegIsKey(UINT root, char *name)
14489 {
14490 return MsRegIsKeyEx(root, name, false);
14491 }
MsRegIsKeyEx(UINT root,char * name,bool force32bit)14492 bool MsRegIsKeyEx(UINT root, char *name, bool force32bit)
14493 {
14494 return MsRegIsKeyEx2(root, name, force32bit, false);
14495 }
MsRegIsKeyEx2(UINT root,char * name,bool force32bit,bool force64bit)14496 bool MsRegIsKeyEx2(UINT root, char *name, bool force32bit, bool force64bit)
14497 {
14498 HKEY h;
14499 // Validate arguments
14500 if (name == NULL)
14501 {
14502 return false;
14503 }
14504
14505 if (RegOpenKeyEx(MsGetRootKeyFromInt(root), name, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
14506 {
14507 return false;
14508 }
14509
14510 RegCloseKey(h);
14511
14512 return true;
14513 }
14514
14515 // Getting root key handle
MsGetRootKeyFromInt(UINT root)14516 HKEY MsGetRootKeyFromInt(UINT root)
14517 {
14518 switch (root)
14519 {
14520 case REG_CLASSES_ROOT:
14521 return HKEY_CLASSES_ROOT;
14522
14523 case REG_LOCAL_MACHINE:
14524 return HKEY_LOCAL_MACHINE;
14525
14526 case REG_CURRENT_USER:
14527 return HKEY_CURRENT_USER;
14528
14529 case REG_USERS:
14530 return HKEY_USERS;
14531 }
14532
14533 return NULL;
14534 }
14535
14536 // Cut the executable file name from the command line string (Unicode version)
MsCutExeNameFromUniCommandLine(wchar_t * str)14537 wchar_t *MsCutExeNameFromUniCommandLine(wchar_t *str)
14538 {
14539 // Validate arguments
14540 if (str == NULL)
14541 {
14542 return NULL;
14543 }
14544
14545 if (str[0] != L'\"')
14546 {
14547 UINT i = UniSearchStrEx(str, L" ", 0, true);
14548 if (i == INFINITE)
14549 {
14550 return str + UniStrLen(str);
14551 }
14552 else
14553 {
14554 return str + i + 1;
14555 }
14556 }
14557 else
14558 {
14559 str++;
14560 while (true)
14561 {
14562 if ((*str) == 0)
14563 {
14564 return str + UniStrLen(str);
14565 }
14566 if ((*str) == L'\"')
14567 {
14568 break;
14569 }
14570 str++;
14571 }
14572
14573 while (true)
14574 {
14575 if ((*str) == 0)
14576 {
14577 return str + UniStrLen(str);
14578 }
14579 if ((*str) == L' ')
14580 {
14581 return str + 1;
14582 }
14583 str++;
14584 }
14585 }
14586 }
14587
14588 // Cut the executable file name from the command line string
MsCutExeNameFromCommandLine(char * str)14589 char *MsCutExeNameFromCommandLine(char *str)
14590 {
14591 // Validate arguments
14592 if (str == NULL)
14593 {
14594 return NULL;
14595 }
14596
14597 if (str[0] != '\"')
14598 {
14599 UINT i = SearchStrEx(str, " ", 0, true);
14600 if (i == INFINITE)
14601 {
14602 return str + StrLen(str);
14603 }
14604 else
14605 {
14606 return str + i + 1;
14607 }
14608 }
14609 else
14610 {
14611 str++;
14612 while (true)
14613 {
14614 if ((*str) == 0)
14615 {
14616 return str + StrLen(str);
14617 }
14618 if ((*str) == '\"')
14619 {
14620 break;
14621 }
14622 str++;
14623 }
14624
14625 while (true)
14626 {
14627 if ((*str) == 0)
14628 {
14629 return str + StrLen(str);
14630 }
14631 if ((*str) == ' ')
14632 {
14633 return str + 1;
14634 }
14635 str++;
14636 }
14637 }
14638 }
14639
14640 // Get the Process handle
MsGetCurrentProcess()14641 void *MsGetCurrentProcess()
14642 {
14643 return ms->hCurrentProcess;
14644 }
14645
14646 // Get the Process ID
MsGetCurrentProcessId()14647 UINT MsGetCurrentProcessId()
14648 {
14649 return ms->CurrentProcessId;
14650 }
14651
14652 // Get the EXE file name
MsGetExeFileName()14653 char *MsGetExeFileName()
14654 {
14655 return ms == NULL ? "Unknown" : ms->ExeFileName;
14656 }
14657
14658 // Get the name of the directory where the EXE file is in
MsGetExeDirName()14659 char *MsGetExeDirName()
14660 {
14661 return ms->ExeFileDir;
14662 }
MsGetExeDirNameW()14663 wchar_t *MsGetExeDirNameW()
14664 {
14665 return ms->ExeFileDirW;
14666 }
14667
14668 // Get the special directory name
MsGetSpecialDir(int id)14669 char *MsGetSpecialDir(int id)
14670 {
14671 LPITEMIDLIST t = NULL;
14672 char tmp[MAX_PATH];
14673
14674 if (SHGetSpecialFolderLocation(NULL, id, &t) != S_OK)
14675 {
14676 return CopyStr(ms->ExeFileDir);
14677 }
14678
14679 if (SHGetPathFromIDList(t, tmp) == false)
14680 {
14681 return CopyStr(ms->ExeFileDir);
14682 }
14683
14684 Win32NukuEn(tmp, sizeof(tmp), tmp);
14685
14686 return CopyStr(tmp);
14687 }
MsGetSpecialDirW(int id)14688 wchar_t *MsGetSpecialDirW(int id)
14689 {
14690 LPITEMIDLIST t = NULL;
14691 wchar_t tmp[MAX_PATH];
14692
14693 if (IsNt() == false)
14694 {
14695 char *tmp = MsGetSpecialDir(id);
14696 wchar_t *ret = CopyStrToUni(tmp);
14697
14698 Free(tmp);
14699
14700 return ret;
14701 }
14702
14703 if (SHGetSpecialFolderLocation(NULL, id, &t) != S_OK)
14704 {
14705 return UniCopyStr(ms->ExeFileDirW);
14706 }
14707
14708 if (SHGetPathFromIDListW(t, tmp) == false)
14709 {
14710 return UniCopyStr(ms->ExeFileDirW);
14711 }
14712
14713 Win32NukuEnW(tmp, sizeof(tmp), tmp);
14714
14715 return UniCopyStr(tmp);
14716 }
14717
14718 // Get all the special directory
MsGetSpecialDirs()14719 void MsGetSpecialDirs()
14720 {
14721 char tmp[MAX_PATH];
14722
14723 // System32
14724 GetSystemDirectory(tmp, sizeof(tmp));
14725 Win32NukuEn(tmp, sizeof(tmp), tmp);
14726 ms->System32Dir = CopyStr(tmp);
14727 ms->System32DirW = CopyStrToUni(tmp);
14728
14729 // The Windows directory is parent of the System32 directory
14730 Win32GetDirFromPath(tmp, sizeof(tmp), tmp);
14731 Win32NukuEn(tmp, sizeof(tmp), tmp);
14732 ms->WindowsDir = CopyStr(tmp);
14733 ms->WindowsDirW = CopyStrToUni(tmp);
14734
14735 // Temp directory under the Windows directory
14736 Format(tmp, sizeof(tmp), "%s\\Temp", ms->WindowsDir);
14737 ms->WinTempDir = CopyStr(tmp);
14738 ms->WinTempDirW = CopyStrToUni(tmp);
14739 MsUniMakeDirEx(ms->WinTempDirW);
14740
14741 // System drive
14742 tmp[2] = 0;
14743 ms->WindowsDrive = CopyStr(tmp);
14744 ms->WindowsDriveW = CopyStrToUni(tmp);
14745
14746 // Temp
14747 GetTempPath(MAX_PATH, tmp);
14748 Win32NukuEn(tmp, sizeof(tmp), tmp);
14749 ms->TempDir = CopyStr(tmp);
14750
14751 // Get the Temp (Unicode)
14752 if (IsNt())
14753 {
14754 wchar_t tmp_w[MAX_PATH];
14755
14756 GetTempPathW(MAX_PATH, tmp_w);
14757 Win32NukuEnW(tmp_w, sizeof(tmp_w), tmp_w);
14758
14759 ms->TempDirW = CopyUniStr(tmp_w);
14760 }
14761 else
14762 {
14763 ms->TempDirW = CopyStrToUni(tmp);
14764 }
14765 MakeDirExW(ms->TempDirW);
14766 MakeDirEx(ms->TempDir);
14767
14768 // Program Files
14769 ms->ProgramFilesDir = MsGetSpecialDir(CSIDL_PROGRAM_FILES);
14770 if (StrCmpi(ms->ProgramFilesDir, ms->ExeFileDir) == 0)
14771 {
14772 char tmp[MAX_PATH];
14773 Format(tmp, sizeof(tmp), "%s\\Program Files", ms->WindowsDrive);
14774
14775 Free(ms->ProgramFilesDir);
14776 ms->ProgramFilesDir = CopyStr(tmp);
14777 }
14778
14779 ms->ProgramFilesDirW = MsGetSpecialDirW(CSIDL_PROGRAM_FILES);
14780 if (UniStrCmpi(ms->ProgramFilesDirW, ms->ExeFileDirW) == 0)
14781 {
14782 wchar_t tmp[MAX_PATH];
14783 UniFormat(tmp, sizeof(tmp), L"%s\\Program Files", ms->WindowsDriveW);
14784
14785 Free(ms->ProgramFilesDirW);
14786 ms->ProgramFilesDirW = UniCopyStr(tmp);
14787 }
14788
14789 // Program Files (x86)
14790 ms->ProgramFilesDirX86 = MsGetSpecialDir(CSIDL_PROGRAM_FILESX86);
14791 if (StrCmpi(ms->ProgramFilesDirX86, ms->ExeFileDir) == 0)
14792 {
14793 if (MsIs64BitWindows())
14794 {
14795 char tmp[MAX_PATH];
14796 Format(tmp, sizeof(tmp), "%s\\Program Files (x86)", ms->WindowsDrive);
14797
14798 Free(ms->ProgramFilesDirX86);
14799 ms->ProgramFilesDirX86 = CopyStr(tmp);
14800 }
14801 else
14802 {
14803 Free(ms->ProgramFilesDirX86);
14804 ms->ProgramFilesDirX86 = CopyStr(ms->ProgramFilesDir);
14805 }
14806 }
14807
14808 ms->ProgramFilesDirX86W = MsGetSpecialDirW(CSIDL_PROGRAM_FILESX86);
14809 if (UniStrCmpi(ms->ProgramFilesDirX86W, ms->ExeFileDirW) == 0)
14810 {
14811 if (MsIs64BitWindows())
14812 {
14813 wchar_t tmp[MAX_PATH];
14814 UniFormat(tmp, sizeof(tmp), L"%s\\Program Files (x86)", ms->WindowsDriveW);
14815
14816 Free(ms->ProgramFilesDirX86W);
14817 ms->ProgramFilesDirX86W = UniCopyStr(tmp);
14818 }
14819 else
14820 {
14821 Free(ms->ProgramFilesDirX86W);
14822 ms->ProgramFilesDirX86W = UniCopyStr(ms->ProgramFilesDirW);
14823 }
14824 }
14825
14826 // Program Files (x64)
14827 if (MsIs64BitWindows())
14828 {
14829 if (Is64())
14830 {
14831 ms->ProgramFilesDirX64 = CopyStr(ms->ProgramFilesDir);
14832 ms->ProgramFilesDirX64W = CopyUniStr(ms->ProgramFilesDirW);
14833 }
14834 else
14835 {
14836 char tmpa[MAX_SIZE];
14837 wchar_t tmpw[MAX_SIZE];
14838
14839 ReplaceStrEx(tmpa, sizeof(tmpa), ms->ProgramFilesDir, "\\Program Files (x86)", "\\Program Files", false);
14840 UniReplaceStrEx(tmpw, sizeof(tmpw), ms->ProgramFilesDirW, L"\\Program Files (x86)", L"\\Program Files", false);
14841
14842 ms->ProgramFilesDirX64 = CopyStr(tmpa);
14843 ms->ProgramFilesDirX64W = CopyUniStr(tmpw);
14844 }
14845 }
14846 else
14847 {
14848 ms->ProgramFilesDirX64 = CopyStr(ms->ProgramFilesDir);
14849 ms->ProgramFilesDirX64W = CopyUniStr(ms->ProgramFilesDirW);
14850 }
14851
14852 if (MsIsNt())
14853 {
14854 // Common start menu
14855 ms->CommonStartMenuDir = MsGetSpecialDir(CSIDL_COMMON_STARTMENU);
14856 ms->CommonStartMenuDirW = MsGetSpecialDirW(CSIDL_COMMON_STARTMENU);
14857
14858 // Common program
14859 ms->CommonProgramsDir = MsGetSpecialDir(CSIDL_COMMON_PROGRAMS);
14860 ms->CommonProgramsDirW = MsGetSpecialDirW(CSIDL_COMMON_PROGRAMS);
14861
14862 // Common startup
14863 ms->CommonStartupDir = MsGetSpecialDir(CSIDL_COMMON_STARTUP);
14864 ms->CommonStartupDirW = MsGetSpecialDirW(CSIDL_COMMON_STARTUP);
14865
14866 // Common application data
14867 ms->CommonAppDataDir = MsGetSpecialDir(CSIDL_COMMON_APPDATA);
14868 ms->CommonAppDataDirW = MsGetSpecialDirW(CSIDL_COMMON_APPDATA);
14869
14870 // Common desktop
14871 ms->CommonDesktopDir = MsGetSpecialDir(CSIDL_COMMON_DESKTOPDIRECTORY);
14872 ms->CommonDesktopDirW = MsGetSpecialDirW(CSIDL_COMMON_DESKTOPDIRECTORY);
14873
14874 // Local Settings
14875 ms->LocalAppDataDir = MsGetSpecialDir(CSIDL_LOCAL_APPDATA);
14876 ms->LocalAppDataDirW = MsGetSpecialDirW(CSIDL_LOCAL_APPDATA);
14877 }
14878 else
14879 {
14880 // Start menu of the individual
14881 ms->PersonalStartMenuDir = MsGetSpecialDir(CSIDL_STARTMENU);
14882 ms->CommonStartMenuDir = CopyStr(ms->PersonalStartMenuDir);
14883 ms->PersonalStartMenuDirW = MsGetSpecialDirW(CSIDL_STARTMENU);
14884 ms->CommonStartMenuDirW = CopyUniStr(ms->PersonalStartMenuDirW);
14885
14886 // Program of the individual
14887 ms->PersonalProgramsDir = MsGetSpecialDir(CSIDL_PROGRAMS);
14888 ms->CommonProgramsDir = CopyStr(ms->PersonalProgramsDir);
14889 ms->PersonalProgramsDirW = MsGetSpecialDirW(CSIDL_PROGRAMS);
14890 ms->CommonProgramsDirW = CopyUniStr(ms->PersonalProgramsDirW);
14891
14892 // Start-up of the individual
14893 ms->PersonalStartupDir = MsGetSpecialDir(CSIDL_STARTUP);
14894 ms->CommonStartupDir = CopyStr(ms->PersonalStartupDir);
14895 ms->PersonalStartupDirW = MsGetSpecialDirW(CSIDL_STARTUP);
14896 ms->CommonStartupDirW = CopyUniStr(ms->PersonalStartupDirW);
14897
14898 // Application data of the individual
14899 ms->PersonalAppDataDir = MsGetSpecialDir(CSIDL_APPDATA);
14900 ms->CommonAppDataDir = CopyStr(ms->PersonalAppDataDir);
14901 ms->PersonalAppDataDirW = MsGetSpecialDirW(CSIDL_APPDATA);
14902 ms->CommonAppDataDirW = CopyUniStr(ms->PersonalAppDataDirW);
14903
14904 // Desktops of the individual
14905 ms->PersonalDesktopDir = MsGetSpecialDir(CSIDL_DESKTOP);
14906 ms->CommonDesktopDir = CopyStr(ms->PersonalDesktopDir);
14907 ms->PersonalDesktopDirW = MsGetSpecialDirW(CSIDL_DESKTOP);
14908 ms->CommonDesktopDirW = CopyUniStr(ms->PersonalDesktopDirW);
14909
14910 // Local Settings
14911 ms->LocalAppDataDir = CopyStr(ms->PersonalAppDataDir);
14912 ms->LocalAppDataDirW = CopyUniStr(ms->PersonalAppDataDirW);
14913 }
14914 }
14915
14916 // Check whether the current user is a Administrators
MsCheckIsAdmin()14917 bool MsCheckIsAdmin()
14918 {
14919 UCHAR test_bit[32];
14920 UCHAR tmp[32];
14921 UCHAR exe_hash[SHA1_SIZE];
14922 char *name_tag = "Vpn_Check_Admin_Key_%u";
14923 DWORD type;
14924 DWORD size;
14925 char name[MAX_SIZE];
14926
14927 HashSha1(exe_hash, MsGetExeFileNameW(), UniStrLen(MsGetExeFileNameW()));
14928
14929 Format(name, sizeof(name), name_tag, *((UINT *)exe_hash));
14930
14931 Rand(test_bit, sizeof(test_bit));
14932
14933 if (RegSetValueEx(HKEY_LOCAL_MACHINE, name, 0, REG_BINARY, test_bit, sizeof(test_bit)) != ERROR_SUCCESS)
14934 {
14935 return false;
14936 }
14937
14938 size = sizeof(tmp);
14939 if (RegQueryValueEx(HKEY_LOCAL_MACHINE, name, 0, &type, tmp, &size) != ERROR_SUCCESS)
14940 {
14941 RegDeleteValue(HKEY_LOCAL_MACHINE, name);
14942 return false;
14943 }
14944
14945 RegDeleteValue(HKEY_LOCAL_MACHINE, name);
14946
14947 if (Cmp(test_bit, tmp, 32) != 0)
14948 {
14949 return false;
14950 }
14951
14952 return true;
14953 }
14954
14955 // Library initialization
MsInit()14956 void MsInit()
14957 {
14958 char *str_ansi;
14959 wchar_t *str_unicode;
14960 OSVERSIONINFO os;
14961 char tmp[MAX_SIZE];
14962 UINT size;
14963 if (ms != NULL)
14964 {
14965 // Already initialized
14966 return;
14967 }
14968
14969 suspend_handler_singleton = NewCounter();
14970 vlan_card_counter = NewCounter();
14971 vlan_card_should_stop_flag = false;
14972
14973 ms = ZeroMalloc(sizeof(MS));
14974
14975 // Getting instance handle
14976 ms->hInst = GetModuleHandle(NULL);
14977
14978 // Get the KERNEL32.DLL
14979 ms->hKernel32 = LoadLibrary("kernel32.dll");
14980
14981 // Get a command line string from the OS
14982 str_ansi = CopyStr(GetCommandLineA());
14983 Trim(str_ansi);
14984 str_unicode = UniCopyStr(GetCommandLineW());
14985 UniTrim(str_unicode);
14986
14987 SetCommandLineStr(MsCutExeNameFromCommandLine(str_ansi));
14988 SetCommandLineUniStr(MsCutExeNameFromUniCommandLine(str_unicode));
14989
14990 Free(str_unicode);
14991 Free(str_ansi);
14992
14993 // Get the version of the OS
14994 Zero(&os, sizeof(os));
14995 os.dwOSVersionInfoSize = sizeof(os);
14996 GetVersionEx(&os);
14997
14998 if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
14999 {
15000 // NT series
15001 ms->IsNt = true;
15002
15003 ms->nt = MsLoadNtApiFunctions();
15004
15005 if (ms->nt == NULL)
15006 {
15007 ms->IsNt = false;
15008 ms->IsAdmin = true;
15009 }
15010 else
15011 {
15012 // Whether I am an Administrators
15013 ms->IsAdmin = MsCheckIsAdmin();
15014 }
15015 }
15016 else
15017 {
15018 // In 9x system: Impersonate a Administrators always
15019 ms->IsAdmin = true;
15020 }
15021
15022 if (GetProcAddress(ms->hKernel32, "wine_get_unix_file_name") != NULL)
15023 {
15024 ms->IsWine = true;
15025 }
15026
15027 // Get information about the current process
15028 ms->hCurrentProcess = GetCurrentProcess();
15029 ms->CurrentProcessId = GetCurrentProcessId();
15030
15031 // Get the EXE file name
15032 GetModuleFileName(NULL, tmp, sizeof(tmp));
15033 ms->ExeFileName = CopyStr(tmp);
15034 Win32GetDirFromPath(tmp, sizeof(tmp), tmp);
15035 ms->ExeFileDir = CopyStr(tmp);
15036
15037 // Get the EXE file name (Unicode)
15038 if (IsNt())
15039 {
15040 wchar_t tmp_w[MAX_PATH];
15041
15042 GetModuleFileNameW(NULL, tmp_w, sizeof(tmp_w));
15043 ms->ExeFileNameW = CopyUniStr(tmp_w);
15044
15045 Win32GetDirFromPathW(tmp_w, sizeof(tmp_w), tmp_w);
15046 ms->ExeFileDirW = CopyUniStr(tmp_w);
15047 }
15048 else
15049 {
15050 ms->ExeFileNameW = CopyStrToUni(ms->ExeFileName);
15051 ms->ExeFileDirW = CopyStrToUni(ms->ExeFileDir);
15052 }
15053
15054 // Get the special directories
15055 MsGetSpecialDirs();
15056
15057 // Initialize the temporary directory
15058 MsInitTempDir();
15059
15060 // Get the user name
15061 size = sizeof(tmp);
15062 GetUserName(tmp, &size);
15063 ms->UserName = CopyStr(tmp);
15064
15065 // Get the user name (Unicode)
15066 if (IsNt())
15067 {
15068 wchar_t tmp_w[MAX_PATH];
15069
15070 size = sizeof(tmp_w);
15071
15072 GetUserNameW(tmp_w, &size);
15073 ms->UserNameW = CopyUniStr(tmp_w);
15074 }
15075 else
15076 {
15077 ms->UserNameW = CopyStrToUni(ms->UserName);
15078 }
15079
15080 // Get the full user name
15081 if (ms->nt != NULL && ms->nt->GetUserNameExA != NULL)
15082 {
15083 wchar_t tmp_w[MAX_PATH];
15084
15085 size = sizeof(tmp);
15086 if (ms->nt->GetUserNameExA(NameSamCompatible, tmp, &size))
15087 {
15088 ms->UserNameEx = CopyStr(tmp);
15089 }
15090
15091 size = sizeof(tmp_w);
15092 if (ms->nt->GetUserNameExW(NameSamCompatible, tmp_w, &size))
15093 {
15094 ms->UserNameExW = CopyUniStr(tmp_w);
15095 }
15096 }
15097
15098 if (ms->UserNameEx == NULL)
15099 {
15100 ms->UserNameEx = CopyStr(ms->UserName);
15101 }
15102 if (ms->UserNameExW == NULL)
15103 {
15104 ms->UserNameExW = CopyUniStr(ms->UserNameW);
15105 }
15106
15107 // Initialization of the adapter list
15108 MsInitAdapterListModule();
15109
15110 // Initialization of minidump base file name
15111 if (true)
15112 {
15113 wchar_t tmp[MAX_PATH];
15114 if (MsIsAdmin())
15115 {
15116 CombinePathW(tmp, sizeof(tmp), ms->ExeFileDirW, L"vpn_debug\\dump");
15117 }
15118 else
15119 {
15120 CombinePathW(tmp, sizeof(tmp), ms->TempDirW, L"vpn_debug\\dump");
15121 }
15122 ms->MinidumpBaseFileNameW = CopyUniStr(tmp);
15123 }
15124
15125 MsSetEnableMinidump(true);
15126
15127 if (MsIsNt())
15128 {
15129 if (ms->nt->MiniDumpWriteDump != NULL)
15130 {
15131 SetUnhandledExceptionFilter(MsExceptionHandler);
15132 }
15133 }
15134
15135 // Open a LSA handle
15136 hLsa = NULL;
15137 lsa_package_id = 0;
15138 if (MsIsNt())
15139 {
15140 MsEnablePrivilege(SE_TCB_NAME, true);
15141
15142 if (ms->nt->AllocateLocallyUniqueId != NULL &&
15143 ms->nt->LsaConnectUntrusted != NULL &&
15144 ms->nt->LsaLookupAuthenticationPackage != NULL &&
15145 ms->nt->LsaLogonUser != NULL &&
15146 ms->nt->LsaDeregisterLogonProcess != NULL &&
15147 ms->nt->LsaFreeReturnBuffer != NULL)
15148 {
15149 HANDLE h = NULL;
15150 NTSTATUS ret = ms->nt->LsaConnectUntrusted(&h);
15151
15152 if (ret == 0)
15153 {
15154 LSA_STRING pkg_name;
15155 ULONG ul = 0;
15156
15157 Zero(&pkg_name, sizeof(pkg_name));
15158 pkg_name.Buffer = MSV1_0_PACKAGE_NAME;
15159 pkg_name.Length = pkg_name.MaximumLength = StrLen(MSV1_0_PACKAGE_NAME);
15160
15161 ret = ms->nt->LsaLookupAuthenticationPackage(h, &pkg_name, &ul);
15162
15163 if (ret == 0)
15164 {
15165 Zero(&lsa_token_source, sizeof(lsa_token_source));
15166
15167 ms->nt->AllocateLocallyUniqueId(&lsa_token_source.SourceIdentifier);
15168 Copy(lsa_token_source.SourceName, "SE-VPN ", 8);
15169
15170 lsa_package_id = ul;
15171 hLsa = h;
15172 }
15173 else
15174 {
15175 ms->nt->LsaDeregisterLogonProcess(h);
15176 }
15177 }
15178 }
15179 }
15180
15181 // Read the msi.dll
15182 if (hMsi == NULL)
15183 {
15184 hMsi = LoadLibrary("msi.dll");
15185
15186 if (hMsi != NULL)
15187 {
15188 _MsiConfigureProductW =
15189 (UINT (__stdcall *)(LPCWSTR,int,INSTALLSTATE)) GetProcAddress(hMsi, "MsiConfigureProductW");
15190 _MsiGetProductInfoW =
15191 (UINT (__stdcall *)(LPCWSTR,LPCWSTR,LPWSTR,LPDWORD)) GetProcAddress(hMsi, "MsiGetProductInfoW");
15192 _MsiSetInternalUI =
15193 (INSTALLUILEVEL (__stdcall *)(INSTALLUILEVEL,HWND *)) GetProcAddress(hMsi, "MsiSetInternalUI");
15194 _MsiLocateComponentW =
15195 (INSTALLSTATE (__stdcall *)(LPCWSTR,LPWSTR,LPDWORD)) GetProcAddress(hMsi, "MsiLocateComponentW");
15196 }
15197 }
15198
15199 // Lock created
15200 vlan_lock = NewLock();
15201 }
15202
15203 // Uninstall the MSI product
MsMsiUninstall(char * product_code,HWND hWnd,bool * reboot_required)15204 bool MsMsiUninstall(char *product_code, HWND hWnd, bool *reboot_required)
15205 {
15206 wchar_t *product_code_w;
15207 bool ret = false;
15208 INSTALLUILEVEL old_level;
15209 HWND old_hwnd;
15210 UINT r;
15211 // Validate arguments
15212 if (product_code == NULL)
15213 {
15214 return false;
15215 }
15216 if (_MsiSetInternalUI == NULL || _MsiConfigureProductW == NULL)
15217 {
15218 return false;
15219 }
15220
15221 if (reboot_required != NULL)
15222 {
15223 *reboot_required = false;
15224 }
15225
15226 product_code_w = CopyStrToUni(product_code);
15227
15228 old_hwnd = hWnd;
15229 old_level = _MsiSetInternalUI(INSTALLUILEVEL_PROGRESSONLY, &old_hwnd);
15230
15231 r = _MsiConfigureProductW(product_code_w, INSTALLLEVEL_DEFAULT, INSTALLSTATE_ABSENT);
15232
15233 if (r == ERROR_SUCCESS || r == ERROR_SUCCESS_REBOOT_INITIATED || r == ERROR_SUCCESS_REBOOT_REQUIRED)
15234 {
15235 ret = true;
15236
15237 if (r == ERROR_SUCCESS_REBOOT_INITIATED || r == ERROR_SUCCESS_REBOOT_REQUIRED)
15238 {
15239 if (reboot_required != NULL)
15240 {
15241 *reboot_required = true;
15242 }
15243 }
15244 }
15245
15246 if (old_level != INSTALLUILEVEL_NOCHANGE)
15247 {
15248 _MsiSetInternalUI(old_level, &old_hwnd);
15249 }
15250
15251 Free(product_code_w);
15252
15253 return ret;
15254 }
15255
15256 // Get the installation directory of the MSI component
MsGetMsiInstalledDir(char * component_code,wchar_t * dir,UINT dir_size)15257 bool MsGetMsiInstalledDir(char *component_code, wchar_t *dir, UINT dir_size)
15258 {
15259 wchar_t *component_code_w;
15260 bool ret = false;
15261 wchar_t tmp[MAX_SIZE];
15262 UINT sz = sizeof(tmp) / sizeof(wchar_t);
15263 // Validate arguments
15264 if (component_code == NULL || dir == NULL)
15265 {
15266 return false;
15267 }
15268 if (_MsiGetProductInfoW == NULL)
15269 {
15270 return false;
15271 }
15272
15273 component_code_w = CopyStrToUni(component_code);
15274
15275 Zero(tmp, sizeof(tmp));
15276
15277 if (_MsiLocateComponentW(component_code_w, tmp, &sz) == INSTALLSTATE_LOCAL)
15278 {
15279 if (UniIsEmptyStr(tmp) == false)
15280 {
15281 GetDirNameFromFilePathW(dir, dir_size, tmp);
15282 ret = true;
15283 }
15284 }
15285
15286 Free(component_code_w);
15287
15288 return ret;
15289 }
15290
15291 // Determine whether to create a minidump
MsSetEnableMinidump(bool enabled)15292 void MsSetEnableMinidump(bool enabled)
15293 {
15294 ms->MiniDumpEnabled = enabled;
15295 }
15296
15297 // Output the minidump
MsWriteMinidump(wchar_t * filename,void * ex)15298 void MsWriteMinidump(wchar_t *filename, void *ex)
15299 {
15300 wchar_t tmp[MAX_PATH];
15301 wchar_t dir[MAX_PATH];
15302 HANDLE h;
15303 MINIDUMP_EXCEPTION_INFORMATION info;
15304 struct _EXCEPTION_POINTERS *exp = (struct _EXCEPTION_POINTERS *)ex;
15305
15306 if (filename != NULL)
15307 {
15308 UniStrCpy(tmp, sizeof(tmp), filename);
15309 }
15310 else
15311 {
15312 SYSTEMTIME tm;
15313
15314 Zero(&tm, sizeof(tm));
15315 GetLocalTime(&tm);
15316
15317 UniFormat(tmp, sizeof(tmp), L"%s_%04u%02u%02u_%02u%02u%02u.dmp",
15318 ms->MinidumpBaseFileNameW,
15319 tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond);
15320 }
15321
15322 GetDirNameFromFilePathW(dir, sizeof(dir), tmp);
15323
15324 CreateDirectoryW(dir, NULL);
15325
15326 Zero(&info, sizeof(info));
15327
15328 if (exp != NULL)
15329 {
15330 info.ThreadId = GetCurrentThreadId();
15331 info.ExceptionPointers = exp;
15332 info.ClientPointers = true;
15333 }
15334
15335 h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE,
15336 FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
15337 NULL);
15338 if (h != INVALID_HANDLE_VALUE)
15339 {
15340 ms->nt->MiniDumpWriteDump(ms->hCurrentProcess, ms->CurrentProcessId,
15341 h,
15342 MiniDumpNormal | MiniDumpWithFullMemory | MiniDumpWithDataSegs |
15343 MiniDumpWithHandleData
15344 ,
15345 info.ThreadId == 0 ? NULL : &info, NULL, NULL);
15346
15347 FlushFileBuffers(h);
15348 CloseHandle(h);
15349 }
15350 }
15351
15352 // Exception handler
MsExceptionHandler(struct _EXCEPTION_POINTERS * ExceptionInfo)15353 LONG CALLBACK MsExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
15354 {
15355 if (ms->MiniDumpEnabled)
15356 {
15357 MsWriteMinidump(NULL, ExceptionInfo);
15358 }
15359
15360 return EXCEPTION_CONTINUE_SEARCH;
15361 }
15362
15363 // Release of the library
MsFree()15364 void MsFree()
15365 {
15366 if (ms == NULL)
15367 {
15368 // Uninitialized
15369 return;
15370 }
15371
15372 // Release the LSA
15373 if (hLsa != NULL)
15374 {
15375 ms->nt->LsaDeregisterLogonProcess(hLsa);
15376
15377 hLsa = NULL;
15378 }
15379
15380 // Release of the adapter list
15381 MsFreeAdapterListModule();
15382
15383 // Release of the temporary directory
15384 MsFreeTempDir();
15385
15386 if (ms->IsNt)
15387 {
15388 // Release of NT series API
15389 MsFreeNtApiFunctions(ms->nt);
15390 }
15391
15392 // Memory release
15393 // ANSI
15394 Free(ms->WindowsDir);
15395 Free(ms->System32Dir);
15396 Free(ms->TempDir);
15397 Free(ms->WinTempDir);
15398 Free(ms->WindowsDrive);
15399 Free(ms->ProgramFilesDir);
15400 Free(ms->CommonStartMenuDir);
15401 Free(ms->CommonProgramsDir);
15402 Free(ms->CommonStartupDir);
15403 Free(ms->CommonAppDataDir);
15404 Free(ms->CommonDesktopDir);
15405 Free(ms->PersonalStartMenuDir);
15406 Free(ms->PersonalProgramsDir);
15407 Free(ms->PersonalStartupDir);
15408 Free(ms->PersonalAppDataDir);
15409 Free(ms->PersonalDesktopDir);
15410 Free(ms->MyDocumentsDir);
15411 Free(ms->ExeFileDir);
15412 Free(ms->ExeFileName);
15413 Free(ms->UserName);
15414 Free(ms->UserNameEx);
15415 Free(ms->LocalAppDataDir);
15416 Free(ms->ProgramFilesDirX86);
15417 Free(ms->ProgramFilesDirX64);
15418 // Unicode
15419 Free(ms->WindowsDirW);
15420 Free(ms->System32DirW);
15421 Free(ms->TempDirW);
15422 Free(ms->WinTempDirW);
15423 Free(ms->WindowsDriveW);
15424 Free(ms->ProgramFilesDirW);
15425 Free(ms->CommonStartMenuDirW);
15426 Free(ms->CommonProgramsDirW);
15427 Free(ms->CommonStartupDirW);
15428 Free(ms->CommonAppDataDirW);
15429 Free(ms->CommonDesktopDirW);
15430 Free(ms->PersonalStartMenuDirW);
15431 Free(ms->PersonalProgramsDirW);
15432 Free(ms->PersonalStartupDirW);
15433 Free(ms->PersonalAppDataDirW);
15434 Free(ms->PersonalDesktopDirW);
15435 Free(ms->MyDocumentsDirW);
15436 Free(ms->ExeFileDirW);
15437 Free(ms->ExeFileNameW);
15438 Free(ms->UserNameW);
15439 Free(ms->UserNameExW);
15440 Free(ms->LocalAppDataDirW);
15441 Free(ms->MinidumpBaseFileNameW);
15442 Free(ms->ProgramFilesDirX86W);
15443 Free(ms->ProgramFilesDirX64W);
15444
15445 Free(ms);
15446 ms = NULL;
15447
15448 // Delete the lock
15449 DeleteLock(vlan_lock);
15450 vlan_lock = NULL;
15451
15452 DeleteCounter(suspend_handler_singleton);
15453 suspend_handler_singleton = NULL;
15454
15455 DeleteCounter(vlan_card_counter);
15456 vlan_card_counter = NULL;
15457 vlan_card_should_stop_flag = false;
15458 }
15459
15460 // Directory acquisition related
MsGetCommonAppDataDir()15461 char *MsGetCommonAppDataDir()
15462 {
15463 return ms->CommonAppDataDir;
15464 }
MsGetLocalAppDataDir()15465 char *MsGetLocalAppDataDir()
15466 {
15467 return ms->LocalAppDataDir;
15468 }
MsGetWindowsDir()15469 char *MsGetWindowsDir()
15470 {
15471 return ms->WindowsDir;
15472 }
MsGetWindowsDirW()15473 wchar_t *MsGetWindowsDirW()
15474 {
15475 return ms->WindowsDirW;
15476 }
MsGetSystem32Dir()15477 char *MsGetSystem32Dir()
15478 {
15479 return ms->System32Dir;
15480 }
MsGetTempDir()15481 char *MsGetTempDir()
15482 {
15483 return ms->TempDir;
15484 }
MsGetWindowsDrive()15485 char *MsGetWindowsDrive()
15486 {
15487 return ms->WindowsDrive;
15488 }
MsGetProgramFilesDir()15489 char *MsGetProgramFilesDir()
15490 {
15491 return ms->ProgramFilesDir;
15492 }
MsGetProgramFilesDirX86()15493 char *MsGetProgramFilesDirX86()
15494 {
15495 return ms->ProgramFilesDirX86;
15496 }
MsGetProgramFilesDirX64()15497 char *MsGetProgramFilesDirX64()
15498 {
15499 return ms->ProgramFilesDirX64;
15500 }
MsGetCommonStartMenuDir()15501 char *MsGetCommonStartMenuDir()
15502 {
15503 return ms->CommonStartMenuDir;
15504 }
MsGetCommonProgramsDir()15505 char *MsGetCommonProgramsDir()
15506 {
15507 return ms->CommonProgramsDir;
15508 }
MsGetCommonStartupDir()15509 char *MsGetCommonStartupDir()
15510 {
15511 return ms->CommonStartupDir;
15512 }
MsGetCommonDesktopDir()15513 char *MsGetCommonDesktopDir()
15514 {
15515 return ms->CommonDesktopDir;
15516 }
MsGetPersonalStartMenuDir()15517 char *MsGetPersonalStartMenuDir()
15518 {
15519 if (ms->PersonalStartMenuDir == NULL)
15520 {
15521 ms->PersonalStartMenuDir = MsGetSpecialDir(CSIDL_STARTMENU);
15522 }
15523 return ms->PersonalStartMenuDir;
15524 }
MsGetPersonalProgramsDir()15525 char *MsGetPersonalProgramsDir()
15526 {
15527 if (ms->PersonalProgramsDir == NULL)
15528 {
15529 ms->PersonalProgramsDir = MsGetSpecialDir(CSIDL_PROGRAMS);
15530 }
15531 return ms->PersonalProgramsDir;
15532 }
MsGetPersonalStartupDir()15533 char *MsGetPersonalStartupDir()
15534 {
15535 if (ms->PersonalStartupDir == NULL)
15536 {
15537 ms->PersonalStartupDir = MsGetSpecialDir(CSIDL_STARTUP);
15538 }
15539 return ms->PersonalStartupDir;
15540 }
MsGetPersonalAppDataDir()15541 char *MsGetPersonalAppDataDir()
15542 {
15543 if (ms->PersonalAppDataDir == NULL)
15544 {
15545 ms->PersonalAppDataDir = MsGetSpecialDir(CSIDL_APPDATA);
15546 }
15547 return ms->PersonalAppDataDir;
15548 }
MsGetPersonalDesktopDir()15549 char *MsGetPersonalDesktopDir()
15550 {
15551 if (ms->PersonalDesktopDir == NULL)
15552 {
15553 ms->PersonalDesktopDir = MsGetSpecialDir(CSIDL_DESKTOP);
15554 }
15555 return ms->PersonalDesktopDir;
15556 }
MsGetMyDocumentsDir()15557 char *MsGetMyDocumentsDir()
15558 {
15559 if (ms->MyDocumentsDir == NULL)
15560 {
15561 ms->MyDocumentsDir = MsGetSpecialDir(CSIDL_PERSONAL);
15562 }
15563 return ms->MyDocumentsDir;
15564 }
MsGetMyTempDir()15565 char *MsGetMyTempDir()
15566 {
15567 return ms->MyTempDir;
15568 }
MsGetUserName()15569 char *MsGetUserName()
15570 {
15571 return ms->UserName;
15572 }
MsGetUserNameEx()15573 char *MsGetUserNameEx()
15574 {
15575 return ms->UserNameEx;
15576 }
MsGetWinTempDir()15577 char *MsGetWinTempDir()
15578 {
15579 return ms->WinTempDir;
15580 }
15581
MsGetExeFileNameW()15582 wchar_t *MsGetExeFileNameW()
15583 {
15584 return ms == NULL ? L"Unknown" : ms->ExeFileNameW;
15585 }
MsGetExeFileDirW()15586 wchar_t *MsGetExeFileDirW()
15587 {
15588 return ms->ExeFileDirW;
15589 }
MsGetWindowDirW()15590 wchar_t *MsGetWindowDirW()
15591 {
15592 return ms->WindowsDirW;
15593 }
MsGetSystem32DirW()15594 wchar_t *MsGetSystem32DirW()
15595 {
15596 return ms->System32DirW;
15597 }
MsGetTempDirW()15598 wchar_t *MsGetTempDirW()
15599 {
15600 return ms->TempDirW;
15601 }
MsGetWindowsDriveW()15602 wchar_t *MsGetWindowsDriveW()
15603 {
15604 return ms->WindowsDriveW;
15605 }
MsGetProgramFilesDirW()15606 wchar_t *MsGetProgramFilesDirW()
15607 {
15608 return ms->ProgramFilesDirW;
15609 }
MsGetCommonStartMenuDirW()15610 wchar_t *MsGetCommonStartMenuDirW()
15611 {
15612 return ms->CommonStartMenuDirW;
15613 }
MsGetCommonProgramsDirW()15614 wchar_t *MsGetCommonProgramsDirW()
15615 {
15616 return ms->CommonProgramsDirW;
15617 }
MsGetProgramFilesDirX86W()15618 wchar_t *MsGetProgramFilesDirX86W()
15619 {
15620 return ms->ProgramFilesDirX86W;
15621 }
MsGetProgramFilesDirX64W()15622 wchar_t *MsGetProgramFilesDirX64W()
15623 {
15624 return ms->ProgramFilesDirX64W;
15625 }
MsGetCommonStartupDirW()15626 wchar_t *MsGetCommonStartupDirW()
15627 {
15628 return ms->CommonStartupDirW;
15629 }
MsGetCommonAppDataDirW()15630 wchar_t *MsGetCommonAppDataDirW()
15631 {
15632 return ms->CommonAppDataDirW;
15633 }
MsGetCommonDesktopDirW()15634 wchar_t *MsGetCommonDesktopDirW()
15635 {
15636 return ms->CommonDesktopDirW;
15637 }
MsGetPersonalStartMenuDirW()15638 wchar_t *MsGetPersonalStartMenuDirW()
15639 {
15640 if (ms->PersonalStartMenuDirW == NULL)
15641 {
15642 ms->PersonalStartMenuDirW = MsGetSpecialDirW(CSIDL_STARTMENU);
15643 }
15644
15645 return ms->PersonalStartMenuDirW;
15646 }
MsGetPersonalProgramsDirW()15647 wchar_t *MsGetPersonalProgramsDirW()
15648 {
15649 if (ms->PersonalProgramsDirW == NULL)
15650 {
15651 ms->PersonalProgramsDirW = MsGetSpecialDirW(CSIDL_PROGRAMS);
15652 }
15653
15654 return ms->PersonalProgramsDirW;
15655 }
MsGetPersonalStartupDirW()15656 wchar_t *MsGetPersonalStartupDirW()
15657 {
15658 if (ms->PersonalStartupDirW == NULL)
15659 {
15660 ms->PersonalStartupDirW = MsGetSpecialDirW(CSIDL_STARTUP);
15661 }
15662
15663 return ms->PersonalStartupDirW;
15664 }
MsGetPersonalAppDataDirW()15665 wchar_t *MsGetPersonalAppDataDirW()
15666 {
15667 if (ms->PersonalAppDataDirW == NULL)
15668 {
15669 ms->PersonalAppDataDirW = MsGetSpecialDirW(CSIDL_APPDATA);
15670 }
15671
15672 return ms->PersonalAppDataDirW;
15673 }
MsGetPersonalDesktopDirW()15674 wchar_t *MsGetPersonalDesktopDirW()
15675 {
15676 if (ms->PersonalDesktopDirW == NULL)
15677 {
15678 ms->PersonalDesktopDirW = MsGetSpecialDirW(CSIDL_DESKTOP);
15679 }
15680
15681 return ms->PersonalDesktopDirW;
15682 }
MsGetMyDocumentsDirW()15683 wchar_t *MsGetMyDocumentsDirW()
15684 {
15685 if (ms->MyDocumentsDirW == NULL)
15686 {
15687 ms->MyDocumentsDirW = MsGetSpecialDirW(CSIDL_PERSONAL);
15688 }
15689
15690 return ms->MyDocumentsDirW;
15691 }
MsGetLocalAppDataDirW()15692 wchar_t *MsGetLocalAppDataDirW()
15693 {
15694 return ms->LocalAppDataDirW;
15695 }
MsGetMyTempDirW()15696 wchar_t *MsGetMyTempDirW()
15697 {
15698 return ms->MyTempDirW;
15699 }
MsGetUserNameW()15700 wchar_t *MsGetUserNameW()
15701 {
15702 return ms->UserNameW;
15703 }
MsGetUserNameExW()15704 wchar_t *MsGetUserNameExW()
15705 {
15706 return ms->UserNameExW;
15707 }
MsGetWinTempDirW()15708 wchar_t *MsGetWinTempDirW()
15709 {
15710 return ms->WinTempDirW;
15711 }
15712
15713
15714 #endif // WIN32
15715
15716