@@ -255,12 +255,67 @@ __declspec(dllexport) UINT __stdcall EvaluateWireGuardServices(MSIHANDLE install
255255 return ret == ERROR_SUCCESS ? ret : ERROR_INSTALL_FAILURE ;
256256}
257257
258+ __declspec(dllexport ) UINT __stdcall EvaluateWireGuardComponents (MSIHANDLE installer )
259+ {
260+ UINT ret = ERROR_INSTALL_FAILURE ;
261+ bool is_com_initialized = SUCCEEDED (CoInitialize (NULL ));
262+ INSTALLSTATE component_installed , component_action ;
263+
264+ ret = MsiGetComponentState (installer , TEXT ("WireGuardExecutable" ), & component_installed , & component_action );
265+ if (ret != ERROR_SUCCESS ) {
266+ log_errorf (installer , LOG_LEVEL_ERR , ret , TEXT ("MsiGetComponentState(\"WireGuardExecutable\") failed" ));
267+ goto out ;
268+ }
269+ if (component_action >= INSTALLSTATE_LOCAL ) {
270+ /* WireGuardExecutable component shall be installed or updated. */
271+ } else if (component_action >= INSTALLSTATE_REMOVED ) {
272+ /* WireGuardExecutable component shall be uninstalled. */
273+ TCHAR path [MAX_PATH ];
274+ DWORD path_len = _countof (path );
275+
276+ log_messagef (installer , LOG_LEVEL_INFO , TEXT ("WireGuardExecutable removal scheduled" ));
277+ ret = MsiSetProperty (installer , TEXT ("RemoveConfigFolder" ), TEXT ("remove" ));
278+ if (ret != ERROR_SUCCESS ) {
279+ log_errorf (installer , LOG_LEVEL_ERR , ret , TEXT ("MsiSetProperty(\"RemoveConfigFolder\") failed" ));
280+ goto out ;
281+ }
282+ ret = MsiGetProperty (installer , TEXT ("WireGuardFolder" ), path , & path_len );
283+ if (ret != ERROR_SUCCESS ) {
284+ log_errorf (installer , LOG_LEVEL_ERR , ret , TEXT ("MsiFormatRecord failed" ));
285+ goto out ;
286+ }
287+ if (!PathAppend (path , TEXT ("wireguard.exe" ))) {
288+ log_errorf (installer , LOG_LEVEL_ERR , ret = GetLastError (), TEXT ("PathAppend(\"%1\", \"wireguard.exe\") failed" ), path );
289+ goto out ;
290+ }
291+ ret = MsiSetProperty (installer , TEXT ("RemoveAdapters" ), path );
292+ if (ret != ERROR_SUCCESS ) {
293+ log_errorf (installer , LOG_LEVEL_ERR , ret , TEXT ("MsiSetProperty(\"RemoveAdapters\") failed" ));
294+ goto out ;
295+ }
296+ }
297+ ret = ERROR_SUCCESS ;
298+
299+ out :
300+ if (is_com_initialized )
301+ CoUninitialize ();
302+ return ret == ERROR_SUCCESS ? ret : ERROR_INSTALL_FAILURE ;
303+ }
304+
258305__declspec(dllexport ) UINT __stdcall RemoveConfigFolder (MSIHANDLE installer )
259306{
260307 LSTATUS ret ;
261308 TCHAR path [MAX_PATH ];
309+ DWORD path_len = _countof (path );
262310 bool is_com_initialized = SUCCEEDED (CoInitialize (NULL ));
263311
312+ ret = MsiGetProperty (installer , TEXT ("CustomActionData" ), path , & path_len );
313+ if (ret != ERROR_SUCCESS ) {
314+ log_errorf (installer , LOG_LEVEL_WARN , ret , TEXT ("MsiGetProperty(\"CustomActionData\") failed" ));
315+ goto out ;
316+ }
317+ if (_tcscmp (path , _T ("remove" )))
318+ goto out ;
264319 ret = SHRegGetPath (HKEY_LOCAL_MACHINE , TEXT ("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\S-1-5-18" ),
265320 TEXT ("ProfileImagePath" ), path , 0 );
266321 if (ret != ERROR_SUCCESS ) {
@@ -371,3 +426,68 @@ __declspec(dllexport) UINT __stdcall KillWireGuardProcesses(MSIHANDLE installer)
371426 CoUninitialize ();
372427 return ERROR_SUCCESS ;
373428}
429+
430+ __declspec(dllexport ) UINT __stdcall RemoveAdapters (MSIHANDLE installer )
431+ {
432+ UINT ret ;
433+ bool is_com_initialized = SUCCEEDED (CoInitialize (NULL ));
434+ TCHAR path [MAX_PATH ];
435+ DWORD path_len = _countof (path );
436+ HANDLE pipe ;
437+ char buf [0x200 ];
438+ DWORD offset = 0 , size_read ;
439+ PROCESS_INFORMATION pi ;
440+ STARTUPINFOW si = {
441+ .cb = sizeof (STARTUPINFO ),
442+ .dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES ,
443+ .wShowWindow = SW_HIDE
444+ };
445+
446+ ret = MsiGetProperty (installer , TEXT ("CustomActionData" ), path , & path_len );
447+ if (ret != ERROR_SUCCESS ) {
448+ log_errorf (installer , LOG_LEVEL_WARN , ret , TEXT ("MsiGetProperty(\"CustomActionData\") failed" ));
449+ goto out ;
450+ }
451+ if (!path [0 ])
452+ goto out ;
453+
454+ if (!CreatePipe (& pipe , & si .hStdOutput , NULL , 0 )) {
455+ log_errorf (installer , LOG_LEVEL_WARN , GetLastError (), TEXT ("CreatePipe failed" ));
456+ goto out ;
457+ }
458+ if (!SetHandleInformation (si .hStdOutput , HANDLE_FLAG_INHERIT , HANDLE_FLAG_INHERIT )) {
459+ log_errorf (installer , LOG_LEVEL_WARN , GetLastError (), TEXT ("SetHandleInformation failed" ));
460+ goto cleanup_pipe_w ;
461+ }
462+ if (!CreateProcess (path , TEXT ("wireguard /removealladapters" ), NULL , NULL , TRUE, 0 , NULL , NULL , & si , & pi )) {
463+ log_errorf (installer , LOG_LEVEL_WARN , GetLastError (), TEXT ("Failed to create \"%1\" process" ), path );
464+ goto cleanup_pipe_w ;
465+ }
466+ CloseHandle (si .hStdOutput );
467+ buf [sizeof (buf ) - 1 ] = '\0' ;
468+ while (ReadFile (pipe , buf + offset , sizeof (buf ) - offset - 1 , & size_read , NULL )) {
469+ char * nl ;
470+ buf [offset + size_read ] = '\0' ;
471+ nl = strchr (buf , '\n' );
472+ if (!nl ) {
473+ offset = size_read ;
474+ continue ;
475+ }
476+ nl [0 ] = '\0' ;
477+ log_messagef (installer , LOG_LEVEL_INFO , TEXT ("%1!hs!" ), buf );
478+ offset = strlen (& nl [1 ]);
479+ memmove (buf , & nl [1 ], offset );
480+ }
481+ WaitForSingleObject (pi .hProcess , INFINITE );
482+ CloseHandle (pi .hProcess );
483+ goto cleanup_pipe_r ;
484+
485+ cleanup_pipe_w :
486+ CloseHandle (si .hStdOutput );
487+ cleanup_pipe_r :
488+ CloseHandle (pipe );
489+ out :
490+ if (is_com_initialized )
491+ CoUninitialize ();
492+ return ERROR_SUCCESS ;
493+ }
0 commit comments