@@ -137,10 +137,10 @@ inline bool isInString(LPCWSTR strCheck, LPCSTR, LPCWSTR strW, size_t size)
137137template <typename T>
138138inline bool isDataPath (T sh2)
139139{
140- if ((sh2[0 ] == ' d' || sh2[0 ] == ' D' ) &&
141- (sh2[1 ] == ' a' || sh2[1 ] == ' A' ) &&
142- (sh2[2 ] == ' t' || sh2[2 ] == ' T' ) &&
143- (sh2[3 ] == ' a' || sh2[3 ] == ' A' ))
140+ if (sh2[ 0 ] != ' \0 ' && (sh2[0 ] == ' d' || sh2[0 ] == ' D' ) &&
141+ sh2[ 1 ] != ' \0 ' && (sh2[1 ] == ' a' || sh2[1 ] == ' A' ) &&
142+ sh2[ 2 ] != ' \0 ' && (sh2[2 ] == ' t' || sh2[2 ] == ' T' ) &&
143+ sh2[ 3 ] != ' \0 ' && (sh2[3 ] == ' a' || sh2[3 ] == ' A' ))
144144 {
145145 return true ;
146146 }
@@ -150,34 +150,38 @@ inline bool isDataPath(T sh2)
150150template <typename T>
151151inline bool isEndVideoPath (T sh2)
152152{
153- if ((sh2[0 ] == ' m' || sh2[0 ] == ' M' ) &&
154- (sh2[1 ] == ' o' || sh2[1 ] == ' O' ) &&
155- (sh2[2 ] == ' v' || sh2[2 ] == ' V' ) &&
156- (sh2[3 ] == ' i' || sh2[3 ] == ' I' ) &&
157- (sh2[4 ] == ' e' || sh2[4 ] == ' E' ) &&
158- (sh2[6 ] == ' e' || sh2[6 ] == ' E' ) &&
159- (sh2[7 ] == ' n' || sh2[7 ] == ' N' ) &&
160- (sh2[8 ] == ' d' || sh2[8 ] == ' D' ) &&
161- (sh2[9 ] == ' i' || sh2[9 ] == ' I' ) &&
162- (sh2[10 ] == ' n' || sh2[10 ] == ' N' ) &&
163- (sh2[11 ] == ' g' || sh2[11 ] == ' G' ) &&
164- (sh2[13 ] == ' b' || sh2[13 ] == ' B' ) &&
165- (sh2[14 ] == ' i' || sh2[14 ] == ' I' ) &&
166- (sh2[15 ] == ' k' || sh2[15 ] == ' K' ))
153+ if (sh2[0 ] != ' \0 ' && (sh2[0 ] == ' m' || sh2[0 ] == ' M' ) &&
154+ sh2[1 ] != ' \0 ' && (sh2[1 ] == ' o' || sh2[1 ] == ' O' ) &&
155+ sh2[2 ] != ' \0 ' && (sh2[2 ] == ' v' || sh2[2 ] == ' V' ) &&
156+ sh2[3 ] != ' \0 ' && (sh2[3 ] == ' i' || sh2[3 ] == ' I' ) &&
157+ sh2[4 ] != ' \0 ' && (sh2[4 ] == ' e' || sh2[4 ] == ' E' ) &&
158+ sh2[5 ] != ' \0 ' &&
159+ sh2[6 ] != ' \0 ' && (sh2[6 ] == ' e' || sh2[6 ] == ' E' ) &&
160+ sh2[7 ] != ' \0 ' && (sh2[7 ] == ' n' || sh2[7 ] == ' N' ) &&
161+ sh2[8 ] != ' \0 ' && (sh2[8 ] == ' d' || sh2[8 ] == ' D' ) &&
162+ sh2[9 ] != ' \0 ' && (sh2[9 ] == ' i' || sh2[9 ] == ' I' ) &&
163+ sh2[10 ] != ' \0 ' && (sh2[10 ] == ' n' || sh2[10 ] == ' N' ) &&
164+ sh2[11 ] != ' \0 ' && (sh2[11 ] == ' g' || sh2[11 ] == ' G' ) &&
165+ sh2[12 ] != ' \0 ' &&
166+ sh2[13 ] != ' \0 ' && (sh2[13 ] == ' b' || sh2[13 ] == ' B' ) &&
167+ sh2[14 ] != ' \0 ' && (sh2[14 ] == ' i' || sh2[14 ] == ' I' ) &&
168+ sh2[15 ] != ' \0 ' && (sh2[15 ] == ' k' || sh2[15 ] == ' K' ))
167169 {
168170 return true ;
169171 }
170- if ((sh2[0 ] == ' m' || sh2[0 ] == ' M' ) &&
171- (sh2[1 ] == ' o' || sh2[1 ] == ' O' ) &&
172- (sh2[2 ] == ' v' || sh2[2 ] == ' V' ) &&
173- (sh2[3 ] == ' i' || sh2[3 ] == ' I' ) &&
174- (sh2[4 ] == ' e' || sh2[4 ] == ' E' ) &&
175- (sh2[6 ] == ' e' || sh2[6 ] == ' E' ) &&
176- (sh2[7 ] == ' n' || sh2[7 ] == ' N' ) &&
177- (sh2[8 ] == ' d' || sh2[8 ] == ' D' ) &&
178- (sh2[10 ] == ' b' || sh2[10 ] == ' B' ) &&
179- (sh2[11 ] == ' i' || sh2[11 ] == ' I' ) &&
180- (sh2[12 ] == ' k' || sh2[12 ] == ' K' ))
172+ if (sh2[0 ] != ' \0 ' && (sh2[0 ] == ' m' || sh2[0 ] == ' M' ) &&
173+ sh2[1 ] != ' \0 ' && (sh2[1 ] == ' o' || sh2[1 ] == ' O' ) &&
174+ sh2[2 ] != ' \0 ' && (sh2[2 ] == ' v' || sh2[2 ] == ' V' ) &&
175+ sh2[3 ] != ' \0 ' && (sh2[3 ] == ' i' || sh2[3 ] == ' I' ) &&
176+ sh2[4 ] != ' \0 ' && (sh2[4 ] == ' e' || sh2[4 ] == ' E' ) &&
177+ sh2[5 ] != ' \0 ' &&
178+ sh2[6 ] != ' \0 ' && (sh2[6 ] == ' e' || sh2[6 ] == ' E' ) &&
179+ sh2[7 ] != ' \0 ' && (sh2[7 ] == ' n' || sh2[7 ] == ' N' ) &&
180+ sh2[8 ] != ' \0 ' && (sh2[8 ] == ' d' || sh2[8 ] == ' D' ) &&
181+ sh2[9 ] != ' \0 ' &&
182+ sh2[10 ] != ' \0 ' && (sh2[10 ] == ' b' || sh2[10 ] == ' B' ) &&
183+ sh2[11 ] != ' \0 ' && (sh2[11 ] == ' i' || sh2[11 ] == ' I' ) &&
184+ sh2[12 ] != ' \0 ' && (sh2[12 ] == ' k' || sh2[12 ] == ' K' ))
181185 {
182186 return true ;
183187 }
@@ -187,30 +191,32 @@ inline bool isEndVideoPath(T sh2)
187191template <typename T>
188192inline DWORD getPicPath (T sh2)
189193{
190- if ((sh2[0 ] == ' p' || sh2[0 ] == ' P' ) &&
191- (sh2[1 ] == ' i' || sh2[1 ] == ' I' ) &&
192- (sh2[2 ] == ' c' || sh2[2 ] == ' C' ))
194+ if (sh2[ 0 ] != ' \0 ' && (sh2[0 ] == ' p' || sh2[0 ] == ' P' ) &&
195+ sh2[ 1 ] != ' \0 ' && (sh2[1 ] == ' i' || sh2[1 ] == ' I' ) &&
196+ sh2[ 2 ] != ' \0 ' && (sh2[2 ] == ' c' || sh2[2 ] == ' C' ))
193197 {
194198 return 3 ;
195199 }
196- if ((sh2[0 ] == ' m' || sh2[0 ] == ' M' ) &&
197- (sh2[1 ] == ' e' || sh2[1 ] == ' E' ) &&
198- (sh2[2 ] == ' n' || sh2[2 ] == ' N' ) &&
199- (sh2[3 ] == ' u' || sh2[3 ] == ' U' ) &&
200- (sh2[5 ] == ' m' || sh2[5 ] == ' M' ) &&
201- (sh2[6 ] == ' c' || sh2[6 ] == ' C' ))
200+ if (sh2[0 ] != ' \0 ' && (sh2[0 ] == ' m' || sh2[0 ] == ' M' ) &&
201+ sh2[1 ] != ' \0 ' && (sh2[1 ] == ' e' || sh2[1 ] == ' E' ) &&
202+ sh2[2 ] != ' \0 ' && (sh2[2 ] == ' n' || sh2[2 ] == ' N' ) &&
203+ sh2[3 ] != ' \0 ' && (sh2[3 ] == ' u' || sh2[3 ] == ' U' ) &&
204+ sh2[4 ] != ' \0 ' &&
205+ sh2[5 ] != ' \0 ' && (sh2[5 ] == ' m' || sh2[5 ] == ' M' ) &&
206+ sh2[6 ] != ' \0 ' && (sh2[6 ] == ' c' || sh2[6 ] == ' C' ))
202207 {
203208 return 4 ;
204209 }
205- if ((sh2[0 ] == ' e' || sh2[0 ] == ' E' ) &&
206- (sh2[1 ] == ' t' || sh2[1 ] == ' T' ) &&
207- (sh2[2 ] == ' c' || sh2[2 ] == ' C' ) &&
208- (sh2[4 ] == ' e' || sh2[4 ] == ' E' ) &&
209- (sh2[5 ] == ' f' || sh2[5 ] == ' F' ) &&
210- (sh2[6 ] == ' f' || sh2[6 ] == ' F' ) &&
211- (sh2[7 ] == ' e' || sh2[7 ] == ' E' ) &&
212- (sh2[8 ] == ' c' || sh2[8 ] == ' C' ) &&
213- (sh2[9 ] == ' t' || sh2[9 ] == ' T' ))
210+ if (sh2[0 ] != ' \0 ' && (sh2[0 ] == ' e' || sh2[0 ] == ' E' ) &&
211+ sh2[1 ] != ' \0 ' && (sh2[1 ] == ' t' || sh2[1 ] == ' T' ) &&
212+ sh2[2 ] != ' \0 ' && (sh2[2 ] == ' c' || sh2[2 ] == ' C' ) &&
213+ sh2[3 ] != ' \0 ' &&
214+ sh2[4 ] != ' \0 ' && (sh2[4 ] == ' e' || sh2[4 ] == ' E' ) &&
215+ sh2[5 ] != ' \0 ' && (sh2[5 ] == ' f' || sh2[5 ] == ' F' ) &&
216+ sh2[6 ] != ' \0 ' && (sh2[6 ] == ' f' || sh2[6 ] == ' F' ) &&
217+ sh2[7 ] != ' \0 ' && (sh2[7 ] == ' e' || sh2[7 ] == ' E' ) &&
218+ sh2[8 ] != ' \0 ' && (sh2[8 ] == ' c' || sh2[8 ] == ' C' ) &&
219+ sh2[9 ] != ' \0 ' && (sh2[9 ] == ' t' || sh2[9 ] == ' T' ))
214220 {
215221 return 3 ;
216222 }
@@ -225,14 +231,22 @@ inline T UpdateModPath(T sh2, D str)
225231 return sh2;
226232 }
227233
234+ DWORD StrSize = strlen (sh2);
228235 DWORD padding = 0 ;
236+ bool isEnding = false ;
229237
230238 // Check if data path is found and store location
231239 if (isDataPath (sh2))
232240 {
233241 // Data path found at location '0', do nothing
234242 }
235- else if (isDataPath (sh2 + modLoc))
243+ else if (StrSize + strlen (ModPath (sh2)) + 4 > MAX_PATH)
244+ {
245+ // Game path is too long
246+ LOG_ONCE (__FUNCTION__ " Error: Game path is too long: '" << sh2 << " '" );
247+ return sh2;
248+ }
249+ else if (StrSize > modLoc && isDataPath (sh2 + modLoc))
236250 {
237251 // Data path found at mod location, update padding and initialize
238252 padding = modLoc;
@@ -254,8 +268,11 @@ inline T UpdateModPath(T sh2, D str)
254268 strcpy_s (str + padding + PathLen, MAX_PATH - padding - PathLen, sh2 + padding + 4 );
255269
256270 // Handle end.bik/ending.bik (favor end.bik)
257- if (isEndVideoPath (sh2 + padding + 5 ))
271+ if ((StrSize > padding + PathLen + 1 ) && isEndVideoPath (sh2 + padding + PathLen + 1 ))
258272 {
273+ Logging::Log () << __FUNCTION__ " " << sh2;
274+ isEnding = true ;
275+
259276 // Check mod path
260277 strcpy_s (str + padding + PathLen, MAX_PATH - padding - PathLen, GetEnding1 (sh2));
261278 if (PathFileExists (str))
@@ -267,20 +284,6 @@ inline T UpdateModPath(T sh2, D str)
267284 {
268285 return str;
269286 }
270-
271- // Check data path
272- strcpy_s (str, MAX_PATH, sh2);
273- strcpy_s (str + padding + 4 , MAX_PATH - padding - 4 , GetEnding1 (sh2));
274- if (PathFileExists (str))
275- {
276- return str;
277- }
278- strcpy_s (str + padding + 4 , MAX_PATH - padding - 4 , GetEnding2 (sh2));
279- if (PathFileExists (str))
280- {
281- return str;
282- }
283- return sh2;
284287 }
285288
286289 // Handle PS2 low texture mod
@@ -302,6 +305,23 @@ inline T UpdateModPath(T sh2, D str)
302305 }
303306 }
304307
308+ // Handle end.bik/ending.bik (favor end.bik)
309+ if (isEnding)
310+ {
311+ // Check data path
312+ strcpy_s (str, MAX_PATH, sh2);
313+ strcpy_s (str + padding + 4 , MAX_PATH - padding - 4 , GetEnding1 (sh2));
314+ if (PathFileExists (str))
315+ {
316+ return str;
317+ }
318+ strcpy_s (str + padding + 4 , MAX_PATH - padding - 4 , GetEnding2 (sh2));
319+ if (PathFileExists (str))
320+ {
321+ return str;
322+ }
323+ }
324+
305325 return sh2;
306326}
307327
@@ -669,9 +689,9 @@ void InstallFileSystemHooks()
669689 modLoc = wcslen (tmpPath) + 1 ;
670690 size_t modLen = strlen (ModPathA);
671691 picLen = strlen (ModPicPathA);
672- if (modLoc + modLen > MAX_PATH)
692+ if (modLoc + modLen + 42 > MAX_PATH) // Check max length of a file in the game
673693 {
674- Logging::Log () << __FUNCTION__ " Error: custom mod path length is too long! " << modLoc + modLen;
694+ Logging::Log () << __FUNCTION__ " Error: Game path is too long: " << modLoc + modLen;
675695 DisableFileSystemHooking ();
676696 return ;
677697 }
0 commit comments