MODEMREG.CPP 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer/ WW Library *
  23. * *
  24. * File Name : MODEMREG.CPP *
  25. * *
  26. * Programmer : Steve Tall *
  27. * *
  28. * Start Date : 10/18/96 *
  29. * *
  30. * Last Update : October 18th 1996 [ST] *
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Overview: *
  34. * *
  35. * Functions for obtaining modem infommation from the Win95 registry *
  36. * *
  37. * *
  38. *---------------------------------------------------------------------------------------------*
  39. * *
  40. * Functions: *
  41. * *
  42. * Search_Registry_Key -- Search a registry key and all its subkeys for a given value *
  43. * MREC::ModemRegistryEntryClass -- Constructor for ModemRegistryEntryClass *
  44. * MREC::~ModemRegistryEntryClass -- Destructor.Free all the memory we allocated for modem info*
  45. * *
  46. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  47. #include "modemreg.h"
  48. #include <stdio.h>
  49. extern HKEY Get_Registry_Sub_Key (HKEY base_key, char *search_key, BOOL close);
  50. /***********************************************************************************************
  51. * Search_Registry_Key -- Search a registry key and all its subkeys for a given value *
  52. * *
  53. * *
  54. * *
  55. * INPUT: handle to key to search in *
  56. * name of key to search for *
  57. * value expected in key *
  58. * *
  59. * OUTPUT: Handle to key containing value. Null if not found. *
  60. * *
  61. * WARNINGS: This function reenters itself. *
  62. * *
  63. * HISTORY: *
  64. * 10/18/96 4:01AM ST : Created *
  65. *=============================================================================================*/
  66. HKEY Search_Registry_Key (HKEY key_in, char *value_name, char *search_string)
  67. {
  68. int top_key_index = 0; // Index of topmost key
  69. int retval; // Result of registry api calls
  70. HKEY next_key; // handle of next key examine
  71. HKEY next_search; // handle of next key to search
  72. char *subkey_name = new char [256]; // Area to contain result of key enumeration
  73. unsigned long subkey_name_length = 256; // Length of enumeration result area
  74. FILETIME filetime; // Time key was last touched. Not used.
  75. unsigned long value_type; // Type of data that is contained in a key.
  76. unsigned char *key_value = new unsigned char [256]; // Area to return key values into
  77. unsigned long key_value_length = 256; // Length of key value area
  78. /*
  79. ** Scan through and enumerate all subkeys of this key. Exit the loop when there are
  80. ** no more sub keys to enumerate.
  81. */
  82. do {
  83. subkey_name_length = 256; // Has to be set each time through the loop
  84. /*
  85. ** Get the next key
  86. */
  87. retval = RegEnumKeyEx (key_in, top_key_index++, subkey_name, &subkey_name_length, NULL, NULL, NULL, &filetime);
  88. if ( retval == ERROR_SUCCESS ){
  89. /*
  90. ** Get a handle to this key so we can search it.
  91. */
  92. next_key = Get_Registry_Sub_Key (key_in, subkey_name, FALSE);
  93. if (next_key){
  94. key_value_length = 256; // Has to be set each time through the loop
  95. if ( RegQueryValueEx (next_key, value_name, NULL, &value_type, key_value, &key_value_length) == ERROR_SUCCESS){
  96. /*
  97. ** If this value is type string then do a compare with the value we are looking for
  98. */
  99. if (value_type == REG_SZ && !strcmp ((char*)key_value, search_string)){
  100. /*
  101. ** This is our man. Delete our workspace and return the key handle
  102. */
  103. delete [] subkey_name;
  104. delete [] key_value;
  105. return (next_key);
  106. }
  107. }
  108. /*
  109. ** We didnt find our search value so search this key for more sub keys by reentering
  110. ** this function with the handle of the subkey.
  111. */
  112. next_search = Search_Registry_Key (next_key, value_name, search_string);
  113. RegCloseKey (next_key);
  114. /*
  115. ** If the value was found in a subkey then just return with the key handle.
  116. */
  117. if (next_search){
  118. delete [] subkey_name;
  119. delete [] key_value;
  120. return (next_search);
  121. }
  122. }
  123. }
  124. } while (retval == ERROR_SUCCESS);
  125. /*
  126. ** Clean up and exit.
  127. */
  128. delete [] subkey_name;
  129. delete [] key_value;
  130. return (0);
  131. }
  132. /***********************************************************************************************
  133. * MREC::ModemRegistryEntryClass -- Constructor for ModemRegistryEntryClass *
  134. * *
  135. * This function does all the work in the class. All the registry searching is done here *
  136. * *
  137. * INPUT: Modem number *
  138. * *
  139. * OUTPUT: Nothing *
  140. * *
  141. * WARNINGS: None *
  142. * *
  143. * HISTORY: *
  144. * 10/18/96 4:12AM ST : Created *
  145. *=============================================================================================*/
  146. ModemRegistryEntryClass::ModemRegistryEntryClass (int modem_number)
  147. {
  148. HKEY key;
  149. unsigned char return_buf[256];
  150. DWORD retbuf_size = sizeof(return_buf);
  151. int pnp = 0; //Not a plug n pray modem
  152. /*
  153. ** Initialise all the info we expect from the registry to NULL.
  154. ** Any entries we cant find will just stay NULL.
  155. */
  156. ModemName = NULL;
  157. ModemDeviceName = NULL;
  158. ErrorCorrectionEnable = NULL;
  159. ErrorCorrectionDisable = NULL;
  160. CompressionEnable = NULL;
  161. CompressionDisable = NULL;
  162. HardwareFlowControl = NULL;
  163. NoFlowControl = NULL;
  164. /*
  165. ** Modem info is stored under
  166. ** HKEY_LOCAL_MACHINE / System / CurrentControlSet / Services / Class / Modem / nnnn
  167. ** where nnnn is a four digit modem number.
  168. */
  169. key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "System", FALSE);
  170. if (!key) return;
  171. key = Get_Registry_Sub_Key (key, "CurrentControlSet", TRUE);
  172. if (!key) return;
  173. key = Get_Registry_Sub_Key (key, "Services", TRUE);
  174. if (!key) return;
  175. key = Get_Registry_Sub_Key (key, "Class", TRUE);
  176. if (!key) return;
  177. key = Get_Registry_Sub_Key (key, "Modem", TRUE);
  178. if (!key) return;
  179. char which_modem[5];
  180. sprintf (which_modem, "%04d", modem_number);
  181. /*
  182. ** Get a handle to the modem key if it exists. Then extract the info we need.
  183. */
  184. key = Get_Registry_Sub_Key (key, which_modem, TRUE);
  185. if (!key) return;
  186. /*
  187. ** Get the name of the modem. This is what will be displayed in the modem list presented
  188. ** to the user.
  189. */
  190. if (RegQueryValueEx(key, "Model", NULL, NULL, return_buf, &retbuf_size) != ERROR_SUCCESS){
  191. RegCloseKey (key);
  192. return;
  193. }
  194. ModemName = new char [retbuf_size];
  195. memcpy (ModemName, return_buf, retbuf_size);
  196. /*
  197. ** Find out what COM port the modem is attached to. If this info isnt here, then its a
  198. ** Plug n Pray modem. Set the flag so we know to do the pnp search later.
  199. */
  200. retbuf_size = sizeof (return_buf);
  201. if (RegQueryValueEx(key, "AttachedTo", NULL, NULL, return_buf, &retbuf_size) != ERROR_SUCCESS){
  202. /*
  203. ** Must be a plug n pray modem. Set the flag. We will look for the port later.
  204. */
  205. pnp = 1;
  206. ModemDeviceName = new char [strlen (ModemName)+1];
  207. strcpy (ModemDeviceName, ModemName);
  208. }else{
  209. ModemDeviceName = new char [retbuf_size];
  210. memcpy (ModemDeviceName, return_buf, retbuf_size);
  211. }
  212. /*
  213. ** The list of modem 'AT' commands is stored in the 'Settings' key.
  214. */
  215. key = Get_Registry_Sub_Key (key, "Settings", TRUE);
  216. if (!key) return;
  217. /*
  218. ** Extract the control strings for error control.
  219. */
  220. retbuf_size = sizeof (return_buf);
  221. if (RegQueryValueEx(key, "ErrorControl_On", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
  222. ErrorCorrectionEnable = new char [retbuf_size];
  223. memcpy (ErrorCorrectionEnable, return_buf, retbuf_size);
  224. }
  225. retbuf_size = sizeof (return_buf);
  226. if (RegQueryValueEx(key, "ErrorControl_Off", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
  227. ErrorCorrectionDisable = new char [retbuf_size];
  228. memcpy (ErrorCorrectionDisable, return_buf, retbuf_size);
  229. }
  230. /*
  231. ** Extract the control strings for data compression.
  232. */
  233. retbuf_size = sizeof (return_buf);
  234. if (RegQueryValueEx(key, "Compression_On", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
  235. CompressionEnable = new char [retbuf_size];
  236. memcpy (CompressionEnable, return_buf, retbuf_size);
  237. }
  238. retbuf_size = sizeof (return_buf);
  239. if (RegQueryValueEx(key, "Compression_Off", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
  240. CompressionDisable = new char [retbuf_size];
  241. memcpy (CompressionDisable, return_buf, retbuf_size);
  242. }
  243. /*
  244. ** Extract the control strings for hardware flow control.
  245. */
  246. retbuf_size = sizeof (return_buf);
  247. if (RegQueryValueEx(key, "FlowControl_Hard", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
  248. HardwareFlowControl = new char [retbuf_size];
  249. memcpy (HardwareFlowControl, return_buf, retbuf_size);
  250. }
  251. /*
  252. ** Extract the control strings for no flow control.
  253. */
  254. retbuf_size = sizeof (return_buf);
  255. if (RegQueryValueEx(key, "FlowControl_Off", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
  256. NoFlowControl = new char [retbuf_size];
  257. memcpy (NoFlowControl, return_buf, retbuf_size);
  258. }
  259. RegCloseKey (key);
  260. /*
  261. ** If this is a plug n pray modem then we need to search for the COM port it is
  262. ** attached to.
  263. */
  264. if (pnp){
  265. /*
  266. ** The driver name in the HKEY_LOCAL_MACHINE / Enum section will be Modem\nnnn where nnnn
  267. ** is a four digit modem number.
  268. */
  269. char search_string [256] = {"Modem\\"};
  270. strcat (search_string, which_modem);
  271. /*
  272. ** Search through all the registry entries under HKEY_LOCAL_MACHINE / Enum
  273. */
  274. key = Get_Registry_Sub_Key (HKEY_LOCAL_MACHINE, "Enum", FALSE);
  275. if (!key) return;
  276. HKEY newkey = Search_Registry_Key ( key, "Driver", search_string );
  277. if (newkey){
  278. retbuf_size = sizeof (return_buf);
  279. /*
  280. ** Extract the PORTNAME value. This is the name of the port to use to communicate
  281. ** with the modem.
  282. */
  283. retbuf_size = sizeof (return_buf);
  284. if (RegQueryValueEx(newkey, "PORTNAME", NULL, NULL, return_buf, &retbuf_size) == ERROR_SUCCESS){
  285. if (ModemDeviceName) delete [] ModemDeviceName;
  286. ModemDeviceName = new char [retbuf_size];
  287. memcpy (ModemDeviceName, return_buf, retbuf_size);
  288. }
  289. }
  290. RegCloseKey (key);
  291. }
  292. }
  293. /***********************************************************************************************
  294. * MREC::~ModemRegistryEntryClass -- Destructor.Free all the memory we allocated for modem info*
  295. * *
  296. * *
  297. * *
  298. * INPUT: Nothing *
  299. * *
  300. * OUTPUT: Nothing *
  301. * *
  302. * WARNINGS: None *
  303. * *
  304. * HISTORY: *
  305. * 10/18/96 11:39AM ST : Created *
  306. *=============================================================================================*/
  307. ModemRegistryEntryClass::~ModemRegistryEntryClass (void)
  308. {
  309. if (ModemName) delete [] ModemName;
  310. if (ModemDeviceName) delete [] ModemDeviceName;
  311. if (ErrorCorrectionEnable) delete [] ErrorCorrectionEnable;
  312. if (ErrorCorrectionDisable) delete [] ErrorCorrectionDisable;
  313. if (CompressionEnable) delete [] CompressionEnable;
  314. if (CompressionDisable) delete [] CompressionDisable;
  315. if (HardwareFlowControl) delete [] HardwareFlowControl;
  316. if (NoFlowControl) delete [] NoFlowControl;
  317. }