1 /*
2  * HLLib
3  * Copyright (C) 2006-2012 Ryan Gregg
4 
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later
9  * version.
10  */
11 
12 #include "HLLib.h"
13 #include "DirectoryItems.h"
14 #include "Mappings.h"
15 #include "Streams.h"
16 #include "Packages.h"
17 #include "Wrapper.h"
18 
19 using namespace HLLib;
20 using namespace HLLib::Streams;
21 using namespace HLLib::Mapping;
22 
23 //
24 // Directory Item
25 //
26 
hlItemGetType(const HLDirectoryItem * pItem)27 HLLIB_API HLDirectoryItemType hlItemGetType(const HLDirectoryItem *pItem)
28 {
29 	return static_cast<const CDirectoryItem *>(pItem)->GetType();
30 }
31 
hlItemGetName(const HLDirectoryItem * pItem)32 HLLIB_API const hlChar *hlItemGetName(const HLDirectoryItem *pItem)
33 {
34 	return static_cast<const CDirectoryItem *>(pItem)->GetName();
35 }
36 
hlItemGetID(const HLDirectoryItem * pItem)37 HLLIB_API hlUInt hlItemGetID(const HLDirectoryItem *pItem)
38 {
39 	return static_cast<const CDirectoryItem *>(pItem)->GetID();
40 }
41 
hlItemGetData(const HLDirectoryItem * pItem)42 HLLIB_API const hlVoid *hlItemGetData(const HLDirectoryItem *pItem)
43 {
44 	return static_cast<const CDirectoryItem *>(pItem)->GetData();
45 }
46 
hlItemGetPackage(const HLDirectoryItem * pItem)47 HLLIB_API hlUInt hlItemGetPackage(const HLDirectoryItem *pItem)
48 {
49 	if(bInitialized)
50 	{
51 		const CPackage *pPackage = static_cast<const CDirectoryItem *>(pItem)->GetPackage();
52 
53 		for(hlUInt i = 0; i < (hlUInt)pPackageVector->size(); i++)
54 		{
55 			if((*pPackageVector)[i] == pPackage)
56 			{
57 				return i;
58 			}
59 		}
60 	}
61 
62 	return HL_ID_INVALID;
63 }
64 
hlItemGetParent(HLDirectoryItem * pItem)65 HLLIB_API HLDirectoryItem *hlItemGetParent(HLDirectoryItem *pItem)
66 {
67 	return static_cast<CDirectoryItem *>(pItem)->GetParent();
68 }
69 
hlItemGetSize(const HLDirectoryItem * pItem,hlUInt * pSize)70 HLLIB_API hlBool hlItemGetSize(const HLDirectoryItem *pItem, hlUInt *pSize)
71 {
72 	*pSize = 0;
73 
74 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
75 	{
76 		*pSize = static_cast<const CDirectoryFolder *>(pItem)->GetSize();
77 	}
78 	else if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
79 	{
80 		return static_cast<const CDirectoryFile *>(pItem)->GetSize(*pSize);
81 	}
82 
83 	return hlFalse;
84 }
85 
hlItemGetSizeEx(const HLDirectoryItem * pItem,hlULongLong * pSize)86 HLLIB_API hlBool hlItemGetSizeEx(const HLDirectoryItem *pItem, hlULongLong *pSize)
87 {
88 	*pSize = 0;
89 
90 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
91 	{
92 		*pSize = static_cast<const CDirectoryFolder *>(pItem)->GetSizeEx();
93 	}
94 	else if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
95 	{
96 		hlUInt uiSize;
97 		if(static_cast<const CDirectoryFile *>(pItem)->GetSize(uiSize))
98 		{
99 			*pSize = static_cast<hlULongLong>(uiSize);
100 			return hlTrue;
101 		}
102 	}
103 
104 	return hlFalse;
105 }
106 
hlItemGetSizeOnDisk(const HLDirectoryItem * pItem,hlUInt * pSize)107 HLLIB_API hlBool hlItemGetSizeOnDisk(const HLDirectoryItem *pItem, hlUInt *pSize)
108 {
109 	*pSize = 0;
110 
111 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
112 	{
113 		*pSize = static_cast<const CDirectoryFolder *>(pItem)->GetSizeOnDisk();
114 	}
115 	else if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
116 	{
117 		return static_cast<const CDirectoryFile *>(pItem)->GetSizeOnDisk(*pSize);
118 	}
119 
120 	return hlFalse;
121 }
122 
hlItemGetSizeOnDiskEx(const HLDirectoryItem * pItem,hlULongLong * pSize)123 HLLIB_API hlBool hlItemGetSizeOnDiskEx(const HLDirectoryItem *pItem, hlULongLong *pSize)
124 {
125 	*pSize = 0;
126 
127 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
128 	{
129 		*pSize = static_cast<const CDirectoryFolder *>(pItem)->GetSizeOnDiskEx();
130 	}
131 	else if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
132 	{
133 		hlUInt uiSize;
134 		if(static_cast<const CDirectoryFile *>(pItem)->GetSizeOnDisk(uiSize))
135 		{
136 			*pSize = static_cast<hlULongLong>(uiSize);
137 			return hlTrue;
138 		}
139 	}
140 
141 	return hlFalse;
142 }
143 
hlItemGetPath(const HLDirectoryItem * pItem,hlChar * lpPath,hlUInt uiPathSize)144 HLLIB_API hlVoid hlItemGetPath(const HLDirectoryItem *pItem, hlChar *lpPath, hlUInt uiPathSize)
145 {
146 	static_cast<const CDirectoryItem *>(pItem)->GetPath(lpPath, uiPathSize);
147 }
148 
hlItemExtract(HLDirectoryItem * pItem,const hlChar * lpPath)149 HLLIB_API hlBool hlItemExtract(HLDirectoryItem *pItem, const hlChar *lpPath)
150 {
151 	return static_cast<CDirectoryItem *>(pItem)->Extract(lpPath);
152 }
153 
154 //
155 // Directory Folder
156 //
157 
hlFolderGetCount(const HLDirectoryItem * pItem)158 HLLIB_API hlUInt hlFolderGetCount(const HLDirectoryItem *pItem)
159 {
160 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
161 	{
162 		return static_cast<const CDirectoryFolder *>(pItem)->GetCount();
163 	}
164 
165 	return 0;
166 }
167 
hlFolderGetItem(HLDirectoryItem * pItem,hlUInt uiIndex)168 HLLIB_API HLDirectoryItem *hlFolderGetItem(HLDirectoryItem *pItem, hlUInt uiIndex)
169 {
170 	if(static_cast<CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
171 	{
172 		return static_cast<CDirectoryFolder *>(pItem)->GetItem(uiIndex);
173 	}
174 
175 	return 0;
176 }
177 
hlFolderGetItemByName(HLDirectoryItem * pItem,const hlChar * lpName,HLFindType eFind)178 HLLIB_API HLDirectoryItem *hlFolderGetItemByName(HLDirectoryItem *pItem, const hlChar *lpName, HLFindType eFind)
179 {
180 	if(static_cast<CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
181 	{
182 		return static_cast<CDirectoryFolder *>(pItem)->GetItem(lpName, eFind);
183 	}
184 
185 	return 0;
186 }
187 
hlFolderGetItemByPath(HLDirectoryItem * pItem,const hlChar * lpPath,HLFindType eFind)188 HLLIB_API HLDirectoryItem *hlFolderGetItemByPath(HLDirectoryItem *pItem, const hlChar *lpPath, HLFindType eFind)
189 {
190 	if(static_cast<CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
191 	{
192 		return static_cast<CDirectoryFolder *>(pItem)->GetRelativeItem(lpPath, eFind);
193 	}
194 
195 	return 0;
196 }
197 
hlFolderSort(HLDirectoryItem * pItem,HLSortField eField,HLSortOrder eOrder,hlBool bRecurse)198 HLLIB_API hlVoid hlFolderSort(HLDirectoryItem *pItem, HLSortField eField, HLSortOrder eOrder, hlBool bRecurse)
199 {
200 	if(static_cast<CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
201 	{
202 		return static_cast<CDirectoryFolder *>(pItem)->Sort(eField, eOrder, bRecurse);
203 	}
204 }
205 
hlFolderFindFirst(HLDirectoryItem * pFolder,const hlChar * lpSearch,HLFindType eFind)206 HLLIB_API HLDirectoryItem *hlFolderFindFirst(HLDirectoryItem *pFolder, const hlChar *lpSearch, HLFindType eFind)
207 {
208 	if(static_cast<CDirectoryItem *>(pFolder)->GetType() == HL_ITEM_FOLDER)
209 	{
210 		return static_cast<CDirectoryFolder *>(pFolder)->FindFirst(lpSearch, eFind);
211 	}
212 
213 	return 0;
214 }
215 
hlFolderFindNext(HLDirectoryItem * pFolder,HLDirectoryItem * pItem,const hlChar * lpSearch,HLFindType eFind)216 HLLIB_API HLDirectoryItem *hlFolderFindNext(HLDirectoryItem *pFolder, HLDirectoryItem *pItem, const hlChar *lpSearch, HLFindType eFind)
217 {
218 	if(static_cast<CDirectoryItem *>(pFolder)->GetType() == HL_ITEM_FOLDER)
219 	{
220 		return static_cast<CDirectoryFolder *>(pFolder)->FindNext(static_cast<CDirectoryItem *>(pItem), lpSearch, eFind);
221 	}
222 
223 	return 0;
224 }
225 
hlFolderGetSize(const HLDirectoryItem * pItem,hlBool bRecurse)226 HLLIB_API hlUInt hlFolderGetSize(const HLDirectoryItem *pItem, hlBool bRecurse)
227 {
228 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
229 	{
230 		return static_cast<const CDirectoryFolder *>(pItem)->GetSize(bRecurse);
231 	}
232 
233 	return 0;
234 }
235 
hlFolderGetSizeEx(const HLDirectoryItem * pItem,hlBool bRecurse)236 HLLIB_API hlULongLong hlFolderGetSizeEx(const HLDirectoryItem *pItem, hlBool bRecurse)
237 {
238 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
239 	{
240 		return static_cast<const CDirectoryFolder *>(pItem)->GetSizeEx(bRecurse);
241 	}
242 
243 	return 0;
244 }
245 
hlFolderGetSizeOnDisk(const HLDirectoryItem * pItem,hlBool bRecurse)246 HLLIB_API hlUInt hlFolderGetSizeOnDisk(const HLDirectoryItem *pItem, hlBool bRecurse)
247 {
248 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
249 	{
250 		return static_cast<const CDirectoryFolder *>(pItem)->GetSizeOnDisk(bRecurse);
251 	}
252 
253 	return 0;
254 }
255 
hlFolderGetSizeOnDiskEx(const HLDirectoryItem * pItem,hlBool bRecurse)256 HLLIB_API hlULongLong hlFolderGetSizeOnDiskEx(const HLDirectoryItem *pItem, hlBool bRecurse)
257 {
258 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
259 	{
260 		return static_cast<const CDirectoryFolder *>(pItem)->GetSizeOnDiskEx(bRecurse);
261 	}
262 
263 	return 0;
264 }
265 
hlFolderGetFolderCount(const HLDirectoryItem * pItem,hlBool bRecurse)266 HLLIB_API hlUInt hlFolderGetFolderCount(const HLDirectoryItem *pItem, hlBool bRecurse)
267 {
268 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
269 	{
270 		return static_cast<const CDirectoryFolder *>(pItem)->GetFolderCount(bRecurse);
271 	}
272 
273 	return 0;
274 }
275 
hlFolderGetFileCount(const HLDirectoryItem * pItem,hlBool bRecurse)276 HLLIB_API hlUInt hlFolderGetFileCount(const HLDirectoryItem *pItem, hlBool bRecurse)
277 {
278 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FOLDER)
279 	{
280 		return static_cast<const CDirectoryFolder *>(pItem)->GetFileCount(bRecurse);
281 	}
282 
283 	return 0;
284 }
285 
286 //
287 // Directory File
288 //
289 
hlFileGetExtractable(const HLDirectoryItem * pItem)290 HLLIB_API hlUInt hlFileGetExtractable(const HLDirectoryItem *pItem)
291 {
292 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
293 	{
294 		return static_cast<const CDirectoryFile *>(pItem)->GetExtractable();
295 	}
296 
297 	return 0;
298 }
299 
hlFileGetValidation(const HLDirectoryItem * pItem)300 HLLIB_API HLValidation hlFileGetValidation(const HLDirectoryItem *pItem)
301 {
302 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
303 	{
304 		return static_cast<const CDirectoryFile *>(pItem)->GetValidation();
305 	}
306 
307 	return HL_VALIDATES_ASSUMED_OK;
308 }
309 
hlFileGetSize(const HLDirectoryItem * pItem)310 HLLIB_API hlUInt hlFileGetSize(const HLDirectoryItem *pItem)
311 {
312 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
313 	{
314 		return static_cast<const CDirectoryFile *>(pItem)->GetSize();
315 	}
316 
317 	return 0;
318 }
319 
hlFileGetSizeOnDisk(const HLDirectoryItem * pItem)320 HLLIB_API hlUInt hlFileGetSizeOnDisk(const HLDirectoryItem *pItem)
321 {
322 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
323 	{
324 		return static_cast<const CDirectoryFile *>(pItem)->GetSizeOnDisk();
325 	}
326 
327 	return 0;
328 }
329 
hlFileCreateStream(HLDirectoryItem * pItem,HLStream ** pStream)330 HLLIB_API hlBool hlFileCreateStream(HLDirectoryItem *pItem, HLStream **pStream)
331 {
332 	*pStream = 0;
333 
334 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
335 	{
336 		IStream *pTemp = 0;
337 		hlBool bResult = static_cast<CDirectoryFile *>(pItem)->CreateStream(pTemp);
338 		*pStream = pTemp;
339 
340 		return bResult;
341 	}
342 
343 	return hlFalse;
344 }
345 
hlFileReleaseStream(HLDirectoryItem * pItem,HLStream * pStream)346 HLLIB_API hlVoid hlFileReleaseStream(HLDirectoryItem *pItem, HLStream *pStream)
347 {
348 	if(static_cast<const CDirectoryItem *>(pItem)->GetType() == HL_ITEM_FILE)
349 	{
350 		static_cast<CDirectoryFile *>(pItem)->ReleaseStream(static_cast<IStream *>(pStream));
351 	}
352 }
353 
354 //
355 // Stream
356 //
357 
hlStreamGetType(const HLStream * pStream)358 HLLIB_API HLStreamType hlStreamGetType(const HLStream *pStream)
359 {
360 	return static_cast<const IStream *>(pStream)->GetType();
361 }
362 
hlStreamGetOpened(const HLStream * pStream)363 HLLIB_API hlBool hlStreamGetOpened(const HLStream *pStream)
364 {
365 	return static_cast<const IStream *>(pStream)->GetOpened();
366 }
367 
hlStreamGetMode(const HLStream * pStream)368 HLLIB_API hlUInt hlStreamGetMode(const HLStream *pStream)
369 {
370 	return static_cast<const IStream *>(pStream)->GetMode();
371 }
372 
hlStreamOpen(HLStream * pStream,hlUInt uiMode)373 HLLIB_API hlBool hlStreamOpen(HLStream *pStream, hlUInt uiMode)
374 {
375 	return static_cast<IStream *>(pStream)->Open(uiMode);
376 }
377 
hlStreamClose(HLStream * pStream)378 HLLIB_API hlVoid hlStreamClose(HLStream *pStream)
379 {
380 	static_cast<IStream *>(pStream)->Close();
381 }
382 
hlStreamGetStreamSize(const HLStream * pStream)383 HLLIB_API hlUInt hlStreamGetStreamSize(const HLStream *pStream)
384 {
385 	return static_cast<hlUInt>(static_cast<const IStream *>(pStream)->GetStreamSize());
386 }
387 
hlStreamGetStreamSizeEx(const HLStream * pStream)388 HLLIB_API hlULongLong hlStreamGetStreamSizeEx(const HLStream *pStream)
389 {
390 	return static_cast<const IStream *>(pStream)->GetStreamSize();
391 }
392 
hlStreamGetStreamPointer(const HLStream * pStream)393 HLLIB_API hlUInt hlStreamGetStreamPointer(const HLStream *pStream)
394 {
395 	return static_cast<hlUInt>(static_cast<const IStream *>(pStream)->GetStreamPointer());
396 }
397 
hlStreamGetStreamPointerEx(const HLStream * pStream)398 HLLIB_API hlULongLong hlStreamGetStreamPointerEx(const HLStream *pStream)
399 {
400 	return static_cast<const IStream *>(pStream)->GetStreamPointer();
401 }
402 
hlStreamSeek(HLStream * pStream,hlLongLong iOffset,HLSeekMode eSeekMode)403 HLLIB_API hlUInt hlStreamSeek(HLStream *pStream, hlLongLong iOffset, HLSeekMode eSeekMode)
404 {
405 	return static_cast<hlUInt>(static_cast<IStream *>(pStream)->Seek(iOffset, eSeekMode));
406 }
407 
hlStreamSeekEx(HLStream * pStream,hlLongLong iOffset,HLSeekMode eSeekMode)408 HLLIB_API hlULongLong hlStreamSeekEx(HLStream *pStream, hlLongLong iOffset, HLSeekMode eSeekMode)
409 {
410 	return static_cast<IStream *>(pStream)->Seek(iOffset, eSeekMode);
411 }
412 
hlStreamReadChar(HLStream * pStream,hlChar * pChar)413 HLLIB_API hlBool hlStreamReadChar(HLStream *pStream, hlChar *pChar)
414 {
415 	return static_cast<IStream *>(pStream)->Read(*pChar);
416 }
417 
hlStreamRead(HLStream * pStream,hlVoid * lpData,hlUInt uiBytes)418 HLLIB_API hlUInt hlStreamRead(HLStream *pStream, hlVoid *lpData, hlUInt uiBytes)
419 {
420 	return static_cast<IStream *>(pStream)->Read(lpData, uiBytes);
421 }
422 
hlStreamWriteChar(HLStream * pStream,hlChar iChar)423 HLLIB_API hlBool hlStreamWriteChar(HLStream *pStream, hlChar iChar)
424 {
425 	return static_cast<IStream *>(pStream)->Write(iChar);
426 }
427 
hlStreamWrite(HLStream * pStream,const hlVoid * lpData,hlUInt uiBytes)428 HLLIB_API hlUInt hlStreamWrite(HLStream *pStream, const hlVoid *lpData, hlUInt uiBytes)
429 {
430 	return static_cast<IStream *>(pStream)->Write(lpData, uiBytes);
431 }
432 
433 //
434 // Package
435 //
436 
hlBindPackage(hlUInt uiPackage)437 HLLIB_API hlBool hlBindPackage(hlUInt uiPackage)
438 {
439 	if(!bInitialized)
440 	{
441 		LastError.SetErrorMessage("HLLib not initialized.");
442 		return hlFalse;
443 	}
444 
445 	if(uiPackage >= pPackageVector->size() || (*pPackageVector)[uiPackage] == 0)
446 	{
447 		LastError.SetErrorMessage("Invalid package.");
448 		return hlFalse;
449 	}
450 
451 	pPackage = (*pPackageVector)[uiPackage];
452 
453 	return hlTrue;
454 }
455 
hlGetPackageTypeFromName(const hlChar * lpName)456 HLLIB_API HLPackageType hlGetPackageTypeFromName(const hlChar *lpName)
457 {
458 	const char *lpExt = strrchr(lpName, '.');
459 
460 	if(lpExt == 0)
461 	{
462 		return HL_PACKAGE_NONE;
463 	}
464 
465 	// Create the package.
466 	/*if(stricmp(lpExt, ".bsp") == 0)
467 	{
468 		return HL_PACKAGE_BSP;
469 		return HL_PACKAGE_VBSP;
470 	}
471 	else*/ if(stricmp(lpExt, ".gcf") == 0)
472 	{
473 		return HL_PACKAGE_GCF;
474 	}
475 	else if(stricmp(lpExt, ".ncf") == 0)
476 	{
477 		return HL_PACKAGE_NCF;
478 	}
479 	else if(stricmp(lpExt, ".pak") == 0)
480 	{
481 		return HL_PACKAGE_PAK;
482 	}
483 	else if(stricmp(lpExt, ".vpk") == 0)
484 	{
485 		return HL_PACKAGE_VPK;
486 	}
487 	else if(stricmp(lpExt, ".wad") == 0)
488 	{
489 		return HL_PACKAGE_WAD;
490 	}
491 	else if(stricmp(lpExt, ".xzp") == 0)
492 	{
493 		return HL_PACKAGE_XZP;
494 	}
495 	else if(stricmp(lpExt, ".zip") == 0)
496 	{
497 		return HL_PACKAGE_ZIP;
498 	}
499 
500 	return HL_PACKAGE_NONE;
501 }
502 
503 struct HLPackageTest
504 {
505 	HLPackageType ePackageType;
506 	hlUInt uiTestLength;
507 	hlByte lpTest[HL_DEFAULT_PACKAGE_TEST_BUFFER_SIZE];
508 };
509 
510 HLPackageTest lpPackageTests[] =
511 {
512 	{ HL_PACKAGE_BSP, 4, { 0x1e, 0x00, 0x00, 0x00 } },
513 	{ HL_PACKAGE_GCF, 8, { 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 } },
514 	{ HL_PACKAGE_NCF, 8, { 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 } },
515 	{ HL_PACKAGE_PAK, 4, { 'P', 'A', 'C', 'K' } },
516 	{ HL_PACKAGE_SGA, 8, { '_', 'A', 'R', 'C', 'H', 'I', 'V', 'E' } },
517 	{ HL_PACKAGE_VBSP, 4, { 'V', 'B', 'S', 'P' } },
518 	{ HL_PACKAGE_VPK, 4, { 0x34, 0x12, 0xaa, 0x55 } },
519 	{ HL_PACKAGE_WAD, 4, { 'W', 'A', 'D', '3' } },
520 	{ HL_PACKAGE_XZP, 4, { 'p', 'i', 'Z', 'x' } },
521 	{ HL_PACKAGE_ZIP, 2, { 'P', 'K' } },
522 	{ HL_PACKAGE_NONE, 0, { } }
523 };
524 
hlGetPackageTypeFromMemory(const hlVoid * lpBuffer,hlUInt uiBufferSize)525 HLLIB_API HLPackageType hlGetPackageTypeFromMemory(const hlVoid *lpBuffer, hlUInt uiBufferSize)
526 {
527 	if(uiBufferSize == 0)
528 	{
529 		return HL_PACKAGE_NONE;
530 	}
531 
532 	for(HLPackageTest *pPackageTest = lpPackageTests; pPackageTest->ePackageType != HL_PACKAGE_NONE; pPackageTest++)
533 	{
534 		if(pPackageTest->uiTestLength <= uiBufferSize && memcmp(lpBuffer, pPackageTest->lpTest, pPackageTest->uiTestLength) == 0)
535 		{
536 			return pPackageTest->ePackageType;
537 		}
538 	}
539 
540 	return HL_PACKAGE_NONE;
541 }
542 
hlGetPackageTypeFromStream(HLStream * pStream)543 HLLIB_API HLPackageType hlGetPackageTypeFromStream(HLStream *pStream)
544 {
545 	IStream &Stream = *static_cast<IStream *>(pStream);
546 
547 	hlUInt uiBufferSize;
548 	hlByte lpBuffer[HL_DEFAULT_PACKAGE_TEST_BUFFER_SIZE];
549 
550 	if(Stream.GetOpened())
551 	{
552 		hlULongLong uiPointer = Stream.GetStreamPointer();
553 
554 		uiBufferSize = Stream.Read(lpBuffer, sizeof(lpBuffer));
555 
556 		Stream.Seek(static_cast<hlLongLong>(uiPointer), HL_SEEK_BEGINNING);
557 	}
558 	else
559 	{
560 		if(!Stream.Open(HL_MODE_READ))
561 		{
562 			return HL_PACKAGE_NONE;
563 		}
564 
565 		uiBufferSize = Stream.Read(lpBuffer, sizeof(lpBuffer));
566 
567 		Stream.Close();
568 	}
569 
570 	return hlGetPackageTypeFromMemory(lpBuffer, uiBufferSize);
571 }
572 
hlCreatePackage(HLPackageType ePackageType,hlUInt * uiPackage)573 HLLIB_API hlBool hlCreatePackage(HLPackageType ePackageType, hlUInt *uiPackage)
574 {
575 	if(!bInitialized)
576 	{
577 		LastError.SetErrorMessage("HLLib not initialized.");
578 		return hlFalse;
579 	}
580 
581 	CPackage* pNewPackage = 0;
582 	switch(ePackageType)
583 	{
584 	case HL_PACKAGE_NONE:
585 		LastError.SetErrorMessage("Unsupported package type.");
586 		return hlFalse;
587 		break;
588 	case HL_PACKAGE_BSP:
589 		pNewPackage = new CBSPFile();
590 		break;
591 	case HL_PACKAGE_GCF:
592 		pNewPackage = new CGCFFile();
593 		break;
594 	case HL_PACKAGE_NCF:
595 		pNewPackage = new CNCFFile();
596 		break;
597 	case HL_PACKAGE_PAK:
598 		pNewPackage = new CPAKFile();
599 		break;
600 	case HL_PACKAGE_SGA:
601 		pNewPackage = new CSGAFile();
602 		break;
603 	case HL_PACKAGE_VBSP:
604 		pNewPackage = new CVBSPFile();
605 		break;
606 	case HL_PACKAGE_VPK:
607 		pNewPackage = new CVPKFile();
608 		break;
609 	case HL_PACKAGE_WAD:
610 		pNewPackage = new CWADFile();
611 		break;
612 	case HL_PACKAGE_XZP:
613 		pNewPackage = new CXZPFile();
614 		break;
615 	case HL_PACKAGE_ZIP:
616 		pNewPackage = new CZIPFile();
617 		break;
618 	default:
619 		LastError.SetErrorMessageFormated("Invalid package type %d.", ePackageType);
620 		return hlFalse;
621 	}
622 
623 	for(hlUInt i = 0; i < (hlUInt)pPackageVector->size(); i++)
624 	{
625 		if((*pPackageVector)[i] == 0)
626 		{
627 			(*pPackageVector)[i] = pNewPackage;
628 			*uiPackage = i;
629 			return hlTrue;
630 		}
631 	}
632 
633 	pPackageVector->push_back(pNewPackage);
634 	*uiPackage = (hlUInt)pPackageVector->size() - 1;
635 
636 	return hlTrue;
637 }
638 
hlDeletePackage(hlUInt uiPackage)639 HLLIB_API hlVoid hlDeletePackage(hlUInt uiPackage)
640 {
641 	if(!bInitialized)
642 		return;
643 
644 	if(uiPackage >= pPackageVector->size())
645 		return;
646 
647 	if((*pPackageVector)[uiPackage] == 0)
648 		return;
649 
650 	if((*pPackageVector)[uiPackage] == pPackage)
651 	{
652 		pPackage = 0;
653 	}
654 
655 	delete (*pPackageVector)[uiPackage];
656 	(*pPackageVector)[uiPackage] = 0;
657 }
658 
hlPackageGetType()659 HLLIB_API HLPackageType hlPackageGetType()
660 {
661 	if(pPackage == 0)
662 	{
663 		return HL_PACKAGE_NONE;
664 	}
665 
666 	return pPackage->GetType();
667 }
668 
hlPackageGetExtension()669 HLLIB_API const hlChar *hlPackageGetExtension()
670 {
671 	if(pPackage == 0)
672 	{
673 		return "";
674 	}
675 
676 	return pPackage->GetExtension();
677 }
678 
hlPackageGetDescription()679 HLLIB_API const hlChar *hlPackageGetDescription()
680 {
681 	if(pPackage == 0)
682 	{
683 		return "";
684 	}
685 
686 	return pPackage->GetDescription();
687 }
688 
hlPackageGetOpened()689 HLLIB_API hlBool hlPackageGetOpened()
690 {
691 	if(pPackage == 0)
692 	{
693 		return hlFalse;
694 	}
695 
696 	return pPackage->GetOpened();
697 }
698 
hlPackageOpenFile(const hlChar * lpFileName,hlUInt uiMode)699 HLLIB_API hlBool hlPackageOpenFile(const hlChar *lpFileName, hlUInt uiMode)
700 {
701 	if(pPackage == 0)
702 	{
703 		return hlFalse;
704 	}
705 
706 	return pPackage->Open(lpFileName, uiMode);
707 }
708 
hlPackageOpenMemory(hlVoid * lpData,hlUInt uiBufferSize,hlUInt uiMode)709 HLLIB_API hlBool hlPackageOpenMemory(hlVoid *lpData, hlUInt uiBufferSize, hlUInt uiMode)
710 {
711 	if(pPackage == 0)
712 	{
713 		return hlFalse;
714 	}
715 
716 	return pPackage->Open(lpData, uiBufferSize, uiMode);
717 }
718 
hlPackageOpenProc(hlVoid * pUserData,hlUInt uiMode)719 HLLIB_API hlBool hlPackageOpenProc(hlVoid *pUserData, hlUInt uiMode)
720 {
721 	if(pPackage == 0)
722 	{
723 		return hlFalse;
724 	}
725 
726 	return pPackage->Open(pUserData, uiMode);
727 }
728 
hlPackageOpenStream(HLStream * pStream,hlUInt uiMode)729 HLLIB_API hlBool hlPackageOpenStream(HLStream *pStream, hlUInt uiMode)
730 {
731 	if(pPackage == 0)
732 	{
733 		return hlFalse;
734 	}
735 
736 	return pPackage->Open(*static_cast<IStream *>(pStream), uiMode);
737 }
738 
hlPackageClose()739 HLLIB_API hlVoid hlPackageClose()
740 {
741 	if(pPackage == 0)
742 	{
743 		return;
744 	}
745 
746 	pPackage->Close();
747 }
748 
hlPackageDefragment()749 HLLIB_API hlBool hlPackageDefragment()
750 {
751 	if(pPackage == 0)
752 	{
753 		return hlFalse;
754 	}
755 
756 	return pPackage->Defragment();
757 }
758 
hlPackageGetRoot()759 HLLIB_API HLDirectoryItem *hlPackageGetRoot()
760 {
761 	if(pPackage == 0)
762 	{
763 		return 0;
764 	}
765 
766 	return pPackage->GetRoot();
767 }
768 
hlPackageGetAttributeCount()769 HLLIB_API hlUInt hlPackageGetAttributeCount()
770 {
771 	if(pPackage == 0)
772 	{
773 		return 0;
774 	}
775 
776 	return pPackage->GetAttributeCount();
777 }
778 
hlPackageGetAttributeName(HLPackageAttribute eAttribute)779 HLLIB_API const hlChar *hlPackageGetAttributeName(HLPackageAttribute eAttribute)
780 {
781 	if(pPackage == 0)
782 	{
783 		return 0;
784 	}
785 
786 	return pPackage->GetAttributeName(eAttribute);
787 }
788 
hlPackageGetAttribute(HLPackageAttribute eAttribute,HLAttribute * pAttribute)789 HLLIB_API hlBool hlPackageGetAttribute(HLPackageAttribute eAttribute, HLAttribute *pAttribute)
790 {
791 	pAttribute->eAttributeType = HL_ATTRIBUTE_INVALID;
792 
793 	if(pPackage == 0)
794 	{
795 		return hlFalse;
796 	}
797 
798 	return pPackage->GetAttribute(eAttribute, *pAttribute);
799 }
800 
hlPackageGetItemAttributeCount()801 HLLIB_API hlUInt hlPackageGetItemAttributeCount()
802 {
803 	if(pPackage == 0)
804 	{
805 		return 0;
806 	}
807 
808 	return pPackage->GetItemAttributeCount();
809 }
810 
hlPackageGetItemAttributeName(HLPackageAttribute eAttribute)811 HLLIB_API const hlChar *hlPackageGetItemAttributeName(HLPackageAttribute eAttribute)
812 {
813 	if(pPackage == 0)
814 	{
815 		return 0;
816 	}
817 
818 	return pPackage->GetItemAttributeName(eAttribute);
819 }
820 
hlPackageGetItemAttribute(const HLDirectoryItem * pItem,HLPackageAttribute eAttribute,HLAttribute * pAttribute)821 HLLIB_API hlBool hlPackageGetItemAttribute(const HLDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute *pAttribute)
822 {
823 	pAttribute->eAttributeType = HL_ATTRIBUTE_INVALID;
824 
825 	if(pPackage == 0)
826 	{
827 		return hlFalse;
828 	}
829 
830 	return pPackage->GetItemAttribute(static_cast<const CDirectoryItem *>(pItem), eAttribute, *pAttribute);
831 }
832 
hlPackageGetExtractable(const HLDirectoryItem * pFile,hlBool * pExtractable)833 HLLIB_API hlBool hlPackageGetExtractable(const HLDirectoryItem *pFile, hlBool *pExtractable)
834 {
835 	*pExtractable = hlFalse;
836 
837 	if(pPackage == 0)
838 	{
839 		return hlFalse;
840 	}
841 
842 	if(static_cast<const CDirectoryItem *>(pFile)->GetType() == HL_ITEM_FILE)
843 	{
844 		return pPackage->GetFileExtractable(static_cast<const CDirectoryFile *>(pFile), *pExtractable);
845 	}
846 
847 	return hlFalse;
848 }
849 
hlPackageGetFileSize(const HLDirectoryItem * pFile,hlUInt * pSize)850 HLLIB_API hlBool hlPackageGetFileSize(const HLDirectoryItem *pFile, hlUInt *pSize)
851 {
852 	*pSize = 0;
853 
854 	if(pPackage == 0)
855 	{
856 		return hlFalse;
857 	}
858 
859 	if(static_cast<const CDirectoryItem *>(pFile)->GetType() == HL_ITEM_FILE)
860 	{
861 		return pPackage->GetFileSize(static_cast<const CDirectoryFile *>(pFile), *pSize);
862 	}
863 
864 	return hlFalse;
865 }
866 
hlPackageGetFileSizeOnDisk(const HLDirectoryItem * pFile,hlUInt * pSize)867 HLLIB_API hlBool hlPackageGetFileSizeOnDisk(const HLDirectoryItem *pFile, hlUInt *pSize)
868 {
869 	*pSize = 0;
870 
871 	if(pPackage == 0)
872 	{
873 		return hlFalse;
874 	}
875 
876 	if(static_cast<const CDirectoryItem *>(pFile)->GetType() == HL_ITEM_FILE)
877 	{
878 		return pPackage->GetFileSizeOnDisk(static_cast<const CDirectoryFile *>(pFile), *pSize);
879 	}
880 
881 	return hlFalse;
882 }
883 
hlPackageCreateStream(const HLDirectoryItem * pFile,HLStream ** pStream)884 HLLIB_API hlBool hlPackageCreateStream(const HLDirectoryItem *pFile, HLStream **pStream)
885 {
886 	*pStream = 0;
887 
888 	if(pPackage == 0)
889 	{
890 		return hlFalse;
891 	}
892 
893 	if(static_cast<const CDirectoryItem *>(pFile)->GetType() == HL_ITEM_FILE)
894 	{
895 		IStream *pTemp = 0;
896 		hlBool bResult = pPackage->CreateStream(static_cast<const CDirectoryFile *>(pFile), pTemp);
897 		*pStream = pTemp;
898 
899 		return bResult;
900 	}
901 
902 	return hlFalse;
903 }
904 
hlPackageReleaseStream(HLStream * pStream)905 HLLIB_API hlVoid hlPackageReleaseStream(HLStream *pStream)
906 {
907 	if(pPackage == 0)
908 	{
909 		return;
910 	}
911 
912 	pPackage->ReleaseStream(static_cast<IStream *>(pStream));
913 }
914 
hlNCFFileGetRootPath()915 HLLIB_API const hlChar *hlNCFFileGetRootPath()
916 {
917 	if(pPackage == 0 || pPackage->GetType() != HL_PACKAGE_NCF)
918 	{
919 		return 0;
920 	}
921 
922 	return static_cast<CNCFFile *>(pPackage)->GetRootPath();
923 }
924 
hlNCFFileSetRootPath(const hlChar * lpRootPath)925 HLLIB_API hlVoid hlNCFFileSetRootPath(const hlChar *lpRootPath)
926 {
927 	if(pPackage == 0 || pPackage->GetType() != HL_PACKAGE_NCF)
928 	{
929 		return;
930 	}
931 
932 	static_cast<CNCFFile *>(pPackage)->SetRootPath(lpRootPath);
933 }
934 
hlWADFileGetImageSizePaletted(const HLDirectoryItem * pFile,hlUInt * uiPaletteDataSize,hlUInt * uiPixelDataSize)935 HLLIB_API hlBool hlWADFileGetImageSizePaletted(const HLDirectoryItem *pFile, hlUInt *uiPaletteDataSize, hlUInt *uiPixelDataSize)
936 {
937 	if(pPackage == 0 || pPackage->GetType() != HL_PACKAGE_WAD)
938 	{
939 		return hlFalse;
940 	}
941 
942 	return static_cast<CWADFile *>(pPackage)->GetImageSize(static_cast<const CDirectoryFile *>(pFile), *uiPaletteDataSize, *uiPixelDataSize);
943 }
944 
hlWADFileGetImageDataPaletted(const HLDirectoryItem * pFile,hlUInt * uiWidth,hlUInt * uiHeight,hlByte ** lpPaletteData,hlByte ** lpPixelData)945 HLLIB_API hlBool hlWADFileGetImageDataPaletted(const HLDirectoryItem *pFile, hlUInt *uiWidth, hlUInt *uiHeight, hlByte **lpPaletteData, hlByte **lpPixelData)
946 {
947 	if(pPackage == 0 || pPackage->GetType() != HL_PACKAGE_WAD)
948 	{
949 		return hlFalse;
950 	}
951 
952 	return static_cast<CWADFile *>(pPackage)->GetImageData(static_cast<const CDirectoryFile *>(pFile), *uiWidth, *uiHeight, *lpPaletteData, *lpPixelData);
953 }
954 
hlWADFileGetImageSize(const HLDirectoryItem * pFile,hlUInt * uiPixelDataSize)955 HLLIB_API hlBool hlWADFileGetImageSize(const HLDirectoryItem *pFile, hlUInt *uiPixelDataSize)
956 {
957 	if(pPackage == 0 || pPackage->GetType() != HL_PACKAGE_WAD)
958 	{
959 		return hlFalse;
960 	}
961 
962 	return static_cast<CWADFile *>(pPackage)->GetImageSize(static_cast<const CDirectoryFile *>(pFile), *uiPixelDataSize);
963 }
964 
hlWADFileGetImageData(const HLDirectoryItem * pFile,hlUInt * uiWidth,hlUInt * uiHeight,hlByte ** lpPixelData)965 HLLIB_API hlBool hlWADFileGetImageData(const HLDirectoryItem *pFile, hlUInt *uiWidth, hlUInt *uiHeight, hlByte **lpPixelData)
966 {
967 	if(pPackage == 0 || pPackage->GetType() != HL_PACKAGE_WAD)
968 	{
969 		return hlFalse;
970 	}
971 
972 	return static_cast<CWADFile *>(pPackage)->GetImageData(static_cast<const CDirectoryFile *>(pFile), *uiWidth, *uiHeight, *lpPixelData);
973 }
974