findpatch.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. ** Command & Conquer Generals(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. #include "findpatch.h"
  19. //
  20. // Locate a patch file
  21. // If a patch can be found then TRUE is returned and the name is filled in,
  22. // otherwise FALSE is returned.
  23. //
  24. // Patch Types:
  25. // - *.rtp = RTPatch file that can be applied right now
  26. // - *.exe = Executable that should be put in the RunOnce registry entry & reboot
  27. // - *.exn = Executable that should be run right now
  28. // - *.web = Link to a web page that will have the patch
  29. // - else = File is ignored, possibly a resource file for one of the other types
  30. //
  31. int Find_Patch(OUT char *filename,int maxlen, ConfigFile &config)
  32. {
  33. WIN32_FIND_DATA findData;
  34. char string[128];
  35. HANDLE hFile;
  36. char *extensions[]={"web","exe","exn","rtp",NULL};
  37. int i;
  38. int skuIndex=0;
  39. Wstring key;
  40. Wstring path;
  41. Wstring sku;
  42. char gamePath[MAX_PATH] = "";
  43. bit8 ok;
  44. while(1)
  45. {
  46. //
  47. // Loop through the apps we're responsible for
  48. //
  49. skuIndex++;
  50. ok=Get_App_Dir(gamePath,MAX_PATH,config,skuIndex);
  51. if (ok==FALSE)
  52. break;
  53. i=0;
  54. while(extensions[i++])
  55. {
  56. _chdir(gamePath); // goto the directory with the game
  57. // should probably get the registry entry for the wchat install path
  58. sprintf(string,"patches\\*.%s",extensions[i]);
  59. hFile=FindFirstFile(string,&findData);
  60. if (hFile!=INVALID_HANDLE_VALUE)
  61. {
  62. _getcwd(filename,MAX_PATH);
  63. strcat(filename,"\\patches\\");
  64. strcat(filename,findData.cFileName);
  65. FindClose(hFile);
  66. return(skuIndex);
  67. }
  68. sprintf(string,"download\\*.%s",extensions[i]);
  69. hFile=FindFirstFile(string,&findData);
  70. if (hFile!=INVALID_HANDLE_VALUE)
  71. {
  72. _getcwd(filename,MAX_PATH);
  73. strcat(filename,"\\download\\");
  74. strcat(filename,findData.cFileName);
  75. FindClose(hFile);
  76. return(skuIndex);
  77. }
  78. }
  79. }
  80. return(FALSE);
  81. }
  82. //
  83. // Get the directory for the N'th application in the config file
  84. //
  85. // Returns FALSE if not in the config file or invalid for some reason.
  86. //
  87. bit8 Get_App_Dir(OUT char *filename,int maxlen, ConfigFile &config,int index)
  88. {
  89. char string[128];
  90. Wstring key;
  91. Wstring path;
  92. Wstring sku;
  93. int temp;
  94. char gamePath[MAX_PATH];
  95. sprintf(string,"SKU%d",index);
  96. // Can't find this product
  97. if (config.getString(string,key)==FALSE)
  98. return(FALSE);
  99. DBGMSG("KEY = "<<key.get());
  100. // Get the InstallPath from the specified registry key
  101. temp=0;
  102. temp=key.getToken(temp," ",sku);
  103. path=key;
  104. path.remove(0,temp);
  105. while((*(path.get()))==' ') // remove leading spaces
  106. path.remove(0,1);
  107. DBGMSG("CONFIG: SKU = "<<sku.get()<<" PATH = '"<<path.get()<<"'");
  108. HKEY regKey;
  109. LONG regRetval;
  110. /////////////DWORD regPrevious;
  111. regRetval=RegOpenKeyEx(HKEY_LOCAL_MACHINE,path.get(),0,KEY_READ,&regKey);
  112. if (regRetval!=ERROR_SUCCESS)
  113. {
  114. DBGMSG("RegOpenKey failed");
  115. return(FALSE);
  116. }
  117. DWORD type;
  118. DWORD length=MAX_PATH;
  119. regRetval=RegQueryValueEx(regKey,"InstallPath",NULL,&type,(uint8 *)gamePath,
  120. &length);
  121. DBGMSG("GAME PATH = "<<gamePath);
  122. if ((regRetval!=ERROR_SUCCESS)||(type!=REG_SZ))
  123. {
  124. DBGMSG("Reg failure");
  125. return(FALSE);
  126. }
  127. // Find the last '\\' in a string and put a 0 after it
  128. // If you only put a directory in the InstallPath key instead of a full
  129. // path to a file, you better end the directory with a trailing '\\'!!!
  130. char *cptr=gamePath;
  131. char *tempPtr;
  132. while( (tempPtr=strchr(cptr,'\\')) !=NULL)
  133. cptr=tempPtr+1;
  134. if (cptr)
  135. *cptr=0;
  136. DBGMSG("Game path = "<<gamePath);
  137. strncpy(filename,gamePath,maxlen);
  138. return(TRUE);
  139. }
  140. //
  141. // Delete any patch files
  142. //
  143. void Delete_Patches(ConfigFile &config)
  144. {
  145. char dir[MAX_PATH];
  146. int i=1;
  147. WIN32_FIND_DATA findData;
  148. HANDLE hFile;
  149. DBGMSG("IN DELPATCH");
  150. //
  151. // Loop through all the application directories in the config file
  152. //
  153. while (Get_App_Dir(dir,MAX_PATH,config,i++)==TRUE)
  154. {
  155. // Make sure path is at least 3 for "c:\". I really hope nobody's
  156. // dumb enough to install a game to the root directory. (It's OK though
  157. // since only the '\patches' folder is cleared out.
  158. if (strlen(dir)<3)
  159. continue;
  160. //
  161. // Delete everything in case a .exe patch had some data files it used.
  162. //
  163. strcat(dir,"patches\\*.*");
  164. DBGMSG("DELPATCH: "<<dir);
  165. hFile=FindFirstFile(dir,&findData);
  166. if (hFile!=INVALID_HANDLE_VALUE)
  167. {
  168. if (findData.cFileName[0]!='.')
  169. {
  170. //_unlink(findData.cFileName);
  171. DBGMSG("UNLINK: "<<findData.cFileName);
  172. }
  173. while(FindNextFile(hFile,&findData))
  174. {
  175. if (findData.cFileName[0]!='.')
  176. {
  177. //_unlink(findData.cFileName);
  178. DBGMSG("UNLINK: "<<findData.cFileName);
  179. }
  180. }
  181. } // If there's at least one file
  182. FindClose(hFile);
  183. } // while there's apps in config
  184. return;
  185. }