mirror of
				https://github.com/onyx-and-iris/vmrcli.git
				synced 2025-10-31 05:01:48 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "8bdbfe9b0419812402b7feff78b877cad75c1834" and "a28db25bcca7265b24cc1917feba0662fb8cbc50" have entirely different histories.
		
	
	
		
			8bdbfe9b04
			...
			a28db25bcc
		
	
		
| @ -13,7 +13,7 @@ | ||||
| ## `Use` | ||||
| 
 | ||||
| ```powershell | ||||
| ./vmrcli.exe [-h] [-i] [-k] [-D] [-v] [-c] [-m] [-s] <api commands> | ||||
| ./vmrcli.exe [-h] [-i] [-k] [-D] [-v] [-m] [-s] <api commands> | ||||
| ``` | ||||
| 
 | ||||
| Where: | ||||
| @ -23,7 +23,6 @@ Where: | ||||
| - `k`: The kind of Voicemeeter (basic, banana or potato). Use this to launch the GUI. | ||||
| - `D`: Set log level 0=TRACE, 1=DEBUG, 2=INFO, 3=WARN, 4=ERROR, 5=FATAL | ||||
| - `v`: Enable extra console output (toggle, set messages) | ||||
| - `c`: Load a user configuration (given the file name or a full path) | ||||
| - `m`: Launch the MacroButtons application | ||||
| - `s`: Launch the StreamerView application | ||||
| 
 | ||||
|  | ||||
| @ -3,6 +3,6 @@ | ||||
| 
 | ||||
| #include "VoicemeeterRemote.h" | ||||
| 
 | ||||
| PT_VMR create_interface(); | ||||
| long initialize_dll_interfaces(PT_VMR vmr); | ||||
| 
 | ||||
| #endif /*__CDLL_H__*/ | ||||
							
								
								
									
										117
									
								
								src/cdll.c
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								src/cdll.c
									
									
									
									
									
								
							| @ -3,40 +3,63 @@ | ||||
| #include <windows.h> | ||||
| #include "cdll.h" | ||||
| #include "util.h" | ||||
| #include "log.h" | ||||
| 
 | ||||
| static T_VBVMR_INTERFACE iVMR; | ||||
| /*******************************************************************************/ | ||||
| /**                           GET VOICEMEETER DIRECTORY                       **/ | ||||
| /*******************************************************************************/ | ||||
| 
 | ||||
| static long initialize_dll_interfaces(PT_VMR vmr); | ||||
| static bool registry_get_voicemeeter_folder(char *szDir); | ||||
| #define INSTALLER_UNINST_KEY "VB:Voicemeeter {17359A74-1236-5467}" | ||||
| 
 | ||||
| PT_VMR create_interface() | ||||
| #ifndef KEY_WOW64_32KEY | ||||
| #define KEY_WOW64_32KEY 0x0200 | ||||
| #endif | ||||
| 
 | ||||
| bool __cdecl registry_get_voicemeeter_folder(char *szDir) | ||||
| { | ||||
|     PT_VMR vmr = &iVMR; | ||||
|     int rep; | ||||
|     char szKey[256]; | ||||
|     char sss[1024]; | ||||
|     DWORD nnsize = 1024; | ||||
|     HKEY hkResult; | ||||
|     LONG rep; | ||||
|     DWORD pptype = REG_SZ; | ||||
|     sss[0] = 0; | ||||
|     const char uninstDirKey[] = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; | ||||
| 
 | ||||
|     rep = initialize_dll_interfaces(vmr); | ||||
|     if (rep < 0) | ||||
|     // build Voicemeeter uninstallation key
 | ||||
|     strcpy(szKey, uninstDirKey); | ||||
|     strcat(szKey, "\\"); | ||||
|     strcat(szKey, INSTALLER_UNINST_KEY); | ||||
| 
 | ||||
|     // open key
 | ||||
|     rep = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hkResult); | ||||
|     if (rep != ERROR_SUCCESS) | ||||
|     { | ||||
|         if (rep == -100) | ||||
|         { | ||||
|             log_fatal("Voicemeeter is not installed"); | ||||
|             exit(EXIT_FAILURE); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             log_fatal("Error loading Voicemeeter dll with code %d\n", rep); | ||||
|             exit(EXIT_FAILURE); | ||||
|         } | ||||
|         // if not present we consider running in 64bit mode and force to read 32bit registry
 | ||||
|         rep = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ | KEY_WOW64_32KEY, &hkResult); | ||||
|     } | ||||
|     if (rep != ERROR_SUCCESS) | ||||
|         return false; | ||||
|     // read uninstall path from registry
 | ||||
|     rep = RegQueryValueEx(hkResult, "UninstallString", 0, &pptype, (unsigned char *)sss, &nnsize); | ||||
|     RegCloseKey(hkResult); | ||||
| 
 | ||||
|     return vmr; | ||||
|     if (pptype != REG_SZ) | ||||
|         return false; | ||||
|     if (rep != ERROR_SUCCESS) | ||||
|         return false; | ||||
|     // remove name to get the path only
 | ||||
|     remove_name_in_path(sss); | ||||
|     if (nnsize > 512) | ||||
|         nnsize = 512; | ||||
|     strncpy(szDir, sss, nnsize); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| /*******************************************************************************/ | ||||
| /**                                GET DLL INTERFACE                          **/ | ||||
| /*******************************************************************************/ | ||||
| static long initialize_dll_interfaces(PT_VMR vmr) | ||||
| long initialize_dll_interfaces(PT_VMR vmr) | ||||
| { | ||||
|     HMODULE G_H_Module = NULL; | ||||
|     char szDllName[1024]; | ||||
| @ -146,55 +169,3 @@ static long initialize_dll_interfaces(PT_VMR vmr) | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /*******************************************************************************/ | ||||
| /**                           GET VOICEMEETER DIRECTORY                       **/ | ||||
| /*******************************************************************************/ | ||||
| 
 | ||||
| #define INSTALLER_UNINST_KEY "VB:Voicemeeter {17359A74-1236-5467}" | ||||
| 
 | ||||
| #ifndef KEY_WOW64_32KEY | ||||
| #define KEY_WOW64_32KEY 0x0200 | ||||
| #endif | ||||
| 
 | ||||
| static bool registry_get_voicemeeter_folder(char *szDir) | ||||
| { | ||||
|     char szKey[256]; | ||||
|     char sss[1024]; | ||||
|     DWORD nnsize = 1024; | ||||
|     HKEY hkResult; | ||||
|     LONG rep; | ||||
|     DWORD pptype = REG_SZ; | ||||
|     sss[0] = 0; | ||||
|     const char uninstDirKey[] = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; | ||||
| 
 | ||||
|     // build Voicemeeter uninstallation key
 | ||||
|     strcpy(szKey, uninstDirKey); | ||||
|     strcat(szKey, "\\"); | ||||
|     strcat(szKey, INSTALLER_UNINST_KEY); | ||||
| 
 | ||||
|     // open key
 | ||||
|     rep = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hkResult); | ||||
|     if (rep != ERROR_SUCCESS) | ||||
|     { | ||||
|         // if not present we consider running in 64bit mode and force to read 32bit registry
 | ||||
|         rep = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ | KEY_WOW64_32KEY, &hkResult); | ||||
|     } | ||||
|     if (rep != ERROR_SUCCESS) | ||||
|         return false; | ||||
|     // read uninstall path from registry
 | ||||
|     rep = RegQueryValueEx(hkResult, "UninstallString", 0, &pptype, (unsigned char *)sss, &nnsize); | ||||
|     RegCloseKey(hkResult); | ||||
| 
 | ||||
|     if (pptype != REG_SZ) | ||||
|         return false; | ||||
|     if (rep != ERROR_SUCCESS) | ||||
|         return false; | ||||
|     // remove name to get the path only
 | ||||
|     remove_name_in_path(sss); | ||||
|     if (nnsize > 512) | ||||
|         nnsize = 512; | ||||
|     strncpy(szDir, sss, nnsize); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
							
								
								
									
										67
									
								
								src/vmrcli.c
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								src/vmrcli.c
									
									
									
									
									
								
							| @ -36,10 +36,12 @@ struct result | ||||
|     } val; | ||||
| }; | ||||
| 
 | ||||
| static bool vflag = false; | ||||
| static T_VBVMR_INTERFACE iVMR; | ||||
| bool vflag = false; | ||||
| 
 | ||||
| void help(void); | ||||
| enum kind set_kind(char *kval); | ||||
| int init_voicemeeter(PT_VMR vmr, enum kind kind); | ||||
| void interactive(PT_VMR vmr); | ||||
| void parse_input(PT_VMR vmr, char *input, int len); | ||||
| void parse_command(PT_VMR vmr, char *command); | ||||
| @ -49,11 +51,9 @@ int main(int argc, char *argv[]) | ||||
| { | ||||
|     bool iflag = false, | ||||
|          mflag = false, | ||||
|          sflag = false, | ||||
|          cflag = false; | ||||
|          sflag = false; | ||||
|     int opt; | ||||
|     int dvalue; | ||||
|     char *cvalue; | ||||
|     enum kind kind = BANANAX64; | ||||
| 
 | ||||
|     if (argc == 1) | ||||
| @ -64,7 +64,7 @@ int main(int argc, char *argv[]) | ||||
| 
 | ||||
|     log_set_level(LOG_WARN); | ||||
| 
 | ||||
|     while ((opt = getopt(argc, argv, "hk:msc:iD:v")) != -1) | ||||
|     while ((opt = getopt(argc, argv, "hk:msiD:v")) != -1) | ||||
|     { | ||||
|         switch (opt) | ||||
|         { | ||||
| @ -85,10 +85,6 @@ int main(int argc, char *argv[]) | ||||
|         case 's': | ||||
|             sflag = true; | ||||
|             break; | ||||
|         case 'c': | ||||
|             cflag = true; | ||||
|             cvalue = optarg; | ||||
|             break; | ||||
|         case 'i': | ||||
|             iflag = true; | ||||
|             break; | ||||
| @ -113,12 +109,11 @@ int main(int argc, char *argv[]) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     PT_VMR vmr = create_interface(); | ||||
|     PT_VMR vmr = &iVMR; | ||||
| 
 | ||||
|     int rep = login(vmr, kind); | ||||
|     int rep = init_voicemeeter(vmr, kind); | ||||
|     if (rep != 0) | ||||
|     { | ||||
|         log_fatal("Error logging into the Voicemeeter API"); | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
| 
 | ||||
| @ -134,12 +129,6 @@ int main(int argc, char *argv[]) | ||||
|         run_voicemeeter(vmr, STREAMERVIEW); | ||||
|     } | ||||
| 
 | ||||
|     if (cflag) | ||||
|     { | ||||
|         log_info("Profile %s loaded", cvalue); | ||||
|         set_parameter_string(vmr, "command.load", cvalue); | ||||
|     } | ||||
| 
 | ||||
|     if (iflag) | ||||
|     { | ||||
|         puts("Interactive mode enabled. Enter 'Q' to exit."); | ||||
| @ -155,15 +144,10 @@ int main(int argc, char *argv[]) | ||||
| 
 | ||||
|     rep = logout(vmr); | ||||
|     if (rep == 0) | ||||
|     { | ||||
|         return EXIT_SUCCESS; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         log_fatal("Error logging out of the Voicemeeter API"); | ||||
|         return EXIT_FAILURE; | ||||
| } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief prints the help message | ||||
| @ -172,14 +156,13 @@ int main(int argc, char *argv[]) | ||||
| void help() | ||||
| { | ||||
|     puts( | ||||
|         "Usage: ./vmrcli.exe [-h] [-i] [-k] [-D] [-v] [-c] [-m] [-s] <api commands>\n" | ||||
|         "Usage: ./vmrcli.exe [-h] [-i] [-k] [-D] [-v] [-m] [-s] <api commands>\n" | ||||
|         "Where: \n" | ||||
|         "\th: Prints the help message\n" | ||||
|         "\ti: Enable interactive mode\n" | ||||
|         "\tk: The kind of Voicemeeter (basic, banana, potato)\n" | ||||
|         "\tD: Set log level 0=TRACE, 1=DEBUG, 2=INFO, 3=WARN, 4=ERROR, 5=FATAL\n" | ||||
|         "\tv: Enable extra console output (toggle, set messages)\n" | ||||
|         "\tc: Load a user configuration (given the file name or a full path)\n" | ||||
|         "\tm: Launch the MacroButtons application\n" | ||||
|         "\ts: Launch the StreamerView application"); | ||||
| } | ||||
| @ -219,6 +202,40 @@ enum kind set_kind(char *kval) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Defines the DLL interface as a struct. | ||||
|  * Logs into the API. | ||||
|  * | ||||
|  * @param vmr The API interface as a struct | ||||
|  * @param kind | ||||
|  * @return int | ||||
|  */ | ||||
| int init_voicemeeter(PT_VMR vmr, enum kind kind) | ||||
| { | ||||
|     int rep = initialize_dll_interfaces(vmr); | ||||
|     if (rep < 0) | ||||
|     { | ||||
|         if (rep == -100) | ||||
|         { | ||||
|             log_fatal("Voicemeeter is not installed"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             log_fatal("Error loading Voicemeeter dll with code %d\n", rep); | ||||
|         } | ||||
|         return rep; | ||||
|     } | ||||
| 
 | ||||
|     rep = login(vmr, kind); | ||||
|     if (rep != 0) | ||||
|     { | ||||
|         log_fatal("Error logging into Voicemeeter"); | ||||
|         return rep; | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Continuously read lines from stdin. | ||||
|  * Break if 'Q' is entered on the interactive prompt. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user