Current News
Archived News
Search News
Discussion Forum


Old Forum
Install Programs More Downloads...
Troubleshooting
Source Code
Format Specs.
Misc. Information
Non-SF Stuff
Links




ShadowFlare [Wed, 16 Jan 2013 06:26:20 +0000 (23:26 -0700)]
CwadLib.cpp [new file with mode: 0644]
CwadLib.h [new file with mode: 0644]
Cwad_specs.txt [new file with mode: 0644]
SFTypes.h [new file with mode: 0644]

diff --git a/CwadLib.cpp b/CwadLib.cpp
new file mode 100644 (file)
index 0000000..8238495
--- /dev/null
@@ -0,0 +1,447 @@
+#include "CwadLib.h"
+#include "SFTypes.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef __SYS_ZLIB
+#include "zlib/zlib.h"
+#else
+#include <zlib.h>
+#endif
+
+const UInt32 ID_CWAD = *(UInt32 *)"CWAD";
+const UInt32 ID_SEP = *(UInt32 *)"SEP\0";
+
+typedef struct _CWADFILEHEADER {
+       UInt32 dwPackedSize;
+       UInt32 dwNameLength;
+       UInt32 dwFullSize;
+       UInt32 dwFlags;
+//     char   szFileName[dwNameLength];
+//     UInt8  byData[dwPackedSize];
+} CWADFILEHEADER;
+
+/* struct CWAD {
+       char     IDTag[4] = "CWAD";
+       CWADFILEHEADER Files[];
+}; */
+
+typedef struct _CWADFILE CWADFILE;
+
+typedef struct _CWADARCHIVE {
+       TCHAR *pszFileName;
+       FILE *pFile;
+       unsigned long nStart;
+       unsigned long nEnd;
+       unsigned long nFiles;
+       CWADFILE *pFiles;
+       char *pmszFileList;
+       unsigned long nFileListSize;
+       bool bHasFileNameBlank;
+       long nReferences;
+       bool bOpen;
+} CWADARCHIVE;
+
+typedef struct _CWADFILE {
+       char *pszFileName;
+       CWADARCHIVE *pParentArc;
+       UInt32 dwPackedSize;
+       UInt32 dwFullSize;
+       UInt32 dwFlags;
+       unsigned long nOffset;
+       UInt8 *pBuffer;
+       long nReferences;
+} CWADFILE;
+
+typedef struct _CWADFILEHANDLE {
+       CWADFILE *f;
+       UInt32 dwFilePointer;
+} CWADFILEHANDLE;
+
+void CWadListFilesInternal(void *hCWAD);
+unsigned long CWadFindHeaderAndSize(FILE *hFile, unsigned long *pnCwadEnd);
+void CWadDecryptData(UInt8 *pBuffer, unsigned long nBufferLength);
+
+void * CWadOpenArchive(const TCHAR *pszFileName)
+{
+       if (!pszFileName)
+               return 0;
+
+       unsigned long flen;
+       FILE *pFile;
+       pFile = _tfopen(pszFileName, _T("rb"));
+       if (pFile)
+       {
+               unsigned long nCwadStart = CWadFindHeaderAndSize(pFile, &flen);
+               if (nCwadStart != -1) {
+                       CWADARCHIVE *cOpenArc = (CWADARCHIVE *)malloc(sizeof(CWADARCHIVE));
+                       if (cOpenArc) {
+                               cOpenArc->pFile = pFile;
+                               cOpenArc->nStart = nCwadStart;
+                               cOpenArc->nEnd = flen;
+                               cOpenArc->pmszFileList = 0;
+                               cOpenArc->bHasFileNameBlank = false;
+                               cOpenArc->pFiles = 0;
+                               CWadListFilesInternal(cOpenArc);
+                               if (cOpenArc->pmszFileList) {
+                                       cOpenArc->pszFileName = _tcsdup(pszFileName);
+                                       cOpenArc->nReferences = 0;
+                                       cOpenArc->bOpen = true;
+                                       return cOpenArc;
+                               }
+
+                               free(cOpenArc);
+                       }
+               }
+
+               fclose(pFile);
+       }
+
+       return 0;
+}
+
+bool CWadCloseArchive(void *hCWAD)
+{
+       if (!hCWAD)
+               return false;
+
+       CWADARCHIVE *cOpenArc = (CWADARCHIVE *)hCWAD;
+       if (cOpenArc->nReferences > 0) {
+               cOpenArc->bOpen = false;
+               return false;
+       }
+       fclose(cOpenArc->pFile);
+       if (cOpenArc->pFiles) free(cOpenArc->pFiles);
+       if (cOpenArc->pmszFileList) free(cOpenArc->pmszFileList);
+       if (cOpenArc->pszFileName) free(cOpenArc->pszFileName);
+       free(cOpenArc);
+       return true;
+}
+
+unsigned long CWadGetArchiveInfo(void *hCWAD, int nInfoType)
+{
+       if (!hCWAD)
+               return -1;
+
+       CWADARCHIVE *cOpenArc = (CWADARCHIVE *)hCWAD;
+       switch (nInfoType) {
+       case CWAD_INFO_NUM_FILES:
+               return cOpenArc->nFiles;
+       case CWAD_INFO_SIZE:
+               return cOpenArc->nEnd - cOpenArc->nStart;
+       default:
+               return -1;
+       }
+}
+
+unsigned long CWadListFiles(void *hCWAD, char *pmszBuffer, unsigned long nBufferLength)
+{
+       if (!hCWAD)
+               return 0;
+
+       CWADARCHIVE *cOpenArc = (CWADARCHIVE *)hCWAD;
+       if (pmszBuffer && nBufferLength >= cOpenArc->nFileListSize)
+               memcpy(pmszBuffer, cOpenArc->pmszFileList, cOpenArc->nFileListSize);
+
+       return cOpenArc->nFileListSize;
+}
+
+void CWadListFilesInternal(void *hCWAD)
+{
+       if (!hCWAD)
+               return;
+
+       CWADARCHIVE *cOpenArc = (CWADARCHIVE *)hCWAD;
+       CWADFILEHEADER CwadFile;
+       unsigned long nReqSize = 0;
+       cOpenArc->nFiles = 0;
+       if (cOpenArc->bHasFileNameBlank && cOpenArc->pmszFileList) {
+               *cOpenArc->pmszFileList = 0;
+               nReqSize++;
+       }
+       fseek(cOpenArc->pFile, cOpenArc->nStart + 4, SEEK_SET);
+       for (long fpos = ftell(cOpenArc->pFile); fpos != -1 && fpos + sizeof(CWADFILEHEADER) <= cOpenArc->nEnd; fpos = ftell(cOpenArc->pFile)) {
+               if (fread(&CwadFile, sizeof(CWADFILEHEADER), 1, cOpenArc->pFile) == 1) {
+                       if (cOpenArc->pmszFileList)
+                       {
+                               if (CwadFile.dwNameLength > 0) {
+                                       if (fread(cOpenArc->pmszFileList + nReqSize, CwadFile.dwNameLength, 1, cOpenArc->pFile) == 1)
+                                               CWadDecryptData((UInt8 *)cOpenArc->pmszFileList + nReqSize, CwadFile.dwNameLength);
+                                       cOpenArc->pFiles[cOpenArc->nFiles].pszFileName = cOpenArc->pmszFileList + nReqSize;
+                               }
+                               else
+                                       cOpenArc->pFiles[cOpenArc->nFiles].pszFileName = cOpenArc->pmszFileList;
+                               cOpenArc->pFiles[cOpenArc->nFiles].pParentArc = cOpenArc;
+                               cOpenArc->pFiles[cOpenArc->nFiles].dwPackedSize = CwadFile.dwPackedSize;
+                               cOpenArc->pFiles[cOpenArc->nFiles].dwFullSize = CwadFile.dwFullSize;
+                               cOpenArc->pFiles[cOpenArc->nFiles].dwFlags = CwadFile.dwFlags;
+                               cOpenArc->pFiles[cOpenArc->nFiles].nOffset = fpos + sizeof(CWADFILEHEADER) + CwadFile.dwNameLength;
+                               cOpenArc->pFiles[cOpenArc->nFiles].pBuffer = 0;
+                               cOpenArc->pFiles[cOpenArc->nFiles].nReferences = 0;
+                       }
+                       else {
+                               fseek(cOpenArc->pFile, CwadFile.dwNameLength, SEEK_CUR);
+                       }
+                       nReqSize += CwadFile.dwNameLength;
+                       if (CwadFile.dwNameLength > 0) {
+                               if (cOpenArc->pmszFileList)
+                                       cOpenArc->pmszFileList[nReqSize] = 0;
+                               nReqSize++;
+                       }
+                       else if (!cOpenArc->bHasFileNameBlank) {
+                               cOpenArc->bHasFileNameBlank = true;
+                               nReqSize++;
+                       }
+                       fseek(cOpenArc->pFile, CwadFile.dwPackedSize, SEEK_CUR);
+                       cOpenArc->nFiles++;
+               }
+               else break;
+       }
+       if (cOpenArc->pmszFileList)
+               cOpenArc->pmszFileList[nReqSize] = 0;
+       nReqSize++;
+       if (nReqSize == 1)
+       {
+               if (cOpenArc->pmszFileList)
+                       cOpenArc->pmszFileList[nReqSize] = 0;
+               nReqSize++;
+       }
+       if (!cOpenArc->pmszFileList) {
+               cOpenArc->pmszFileList = (char *)malloc(nReqSize);
+               cOpenArc->nFileListSize = nReqSize;
+               if (cOpenArc->nFiles > 0)
+                       cOpenArc->pFiles = (CWADFILE *)calloc(cOpenArc->nFiles, sizeof(CWADFILE));
+               if (cOpenArc->pmszFileList && (cOpenArc->pFiles || cOpenArc->nFiles == 0))
+                       CWadListFilesInternal(hCWAD);
+               else {
+                       if (cOpenArc->pmszFileList) {
+                               free(cOpenArc->pmszFileList);
+                               cOpenArc->pmszFileList = 0;
+                       }
+                       if (cOpenArc->pFiles)
+                               free(cOpenArc->pFiles);
+               }
+       }
+}
+
+void * CWadOpenFile(void *hCWAD, const char *pszFileName)
+{
+       if (!hCWAD || !pszFileName)
+               return 0;
+
+       CWADARCHIVE *cOpenArc = (CWADARCHIVE *)hCWAD;
+       unsigned long nFile;
+       for (nFile = 0; nFile < cOpenArc->nFiles; nFile++) {
+               if (strcmp(pszFileName, cOpenArc->pFiles[nFile].pszFileName) == 0) {
+                       CWADFILEHANDLE *cOpenFile = (CWADFILEHANDLE *)malloc(sizeof(CWADFILEHANDLE));
+                       if (cOpenFile) {
+                               cOpenFile->f = &cOpenArc->pFiles[nFile];
+                               cOpenFile->dwFilePointer = 0;
+                               cOpenFile->f->nReferences++;
+                               cOpenArc->nReferences++;
+                               return cOpenFile;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+bool CWadCloseFile(void *hFile)
+{
+       if (!hFile)
+               return false;
+
+       CWADFILEHANDLE *cOpenFile = (CWADFILEHANDLE *)hFile;
+       cOpenFile->f->nReferences--;
+       cOpenFile->f->pParentArc->nReferences--;
+       if (cOpenFile->f->nReferences < 1 && cOpenFile->f->pBuffer) {
+               free(cOpenFile->f->pBuffer);
+               cOpenFile->f->pBuffer = 0;
+       }
+       if (cOpenFile->f->pParentArc->nReferences < 1 && !cOpenFile->f->pParentArc->bOpen)
+               CWadCloseArchive(cOpenFile->f->pParentArc);
+       free(cOpenFile);
+
+       return true;
+}
+
+unsigned long CWadGetFileSize(void *hFile)
+{
+       if (!hFile)
+               return -1;
+
+       CWADFILEHANDLE *cOpenFile = (CWADFILEHANDLE *)hFile;
+       return cOpenFile->f->dwFullSize;
+}
+
+unsigned long CWadGetFileInfo(void *hFile, int nInfoType)
+{
+       if (!hFile)
+               return -1;
+
+       CWADFILEHANDLE *cOpenFile = (CWADFILEHANDLE *)hFile;
+       switch (nInfoType) {
+       case CWAD_INFO_NUM_FILES:
+               return cOpenFile->f->pParentArc->nFiles;
+       case CWAD_INFO_SIZE:
+               return cOpenFile->f->dwFullSize;
+       case CWAD_INFO_COMPRESSED_SIZE:
+               return cOpenFile->f->dwPackedSize;
+       case CWAD_INFO_FLAGS:
+               return cOpenFile->f->dwFlags;
+       case CWAD_INFO_PARENT:
+               return (unsigned long)cOpenFile->f->pParentArc;
+       case CWAD_INFO_POSITION:
+               return cOpenFile->dwFilePointer;
+       default:
+               return -1;
+       }
+}
+
+unsigned long CWadSetFilePointer(void *hFile, long nDistanceToMove, int nMoveMethod)
+{
+       if (!hFile)
+               return -1;
+
+       CWADFILEHANDLE *cOpenFile = (CWADFILEHANDLE *)hFile;
+       long fsz = cOpenFile->f->dwFullSize;
+       long cpos = cOpenFile->dwFilePointer;
+       switch (nMoveMethod) {
+       case CWAD_FILE_CURRENT:
+               if (cpos + nDistanceToMove < 0 || cpos + nDistanceToMove > fsz) return -1;
+               cOpenFile->dwFilePointer += nDistanceToMove;
+               break;
+       case CWAD_FILE_END:
+               if (fsz + nDistanceToMove < 0 || nDistanceToMove > 0) return -1;
+               cOpenFile->dwFilePointer = fsz + nDistanceToMove;
+               break;
+       case CWAD_FILE_BEGIN:
+       default:
+               if (nDistanceToMove < 0 || nDistanceToMove > fsz) return -1;
+               cOpenFile->dwFilePointer = nDistanceToMove;
+       }
+
+       return cOpenFile->dwFilePointer;
+}
+
+unsigned long CWadReadFile(void *hFile, void *pBuffer, unsigned long nNumberOfBytesToRead)
+{
+       if (!hFile || !pBuffer || nNumberOfBytesToRead == 0)
+               return 0;
+
+       CWADFILEHANDLE *cOpenFile = (CWADFILEHANDLE *)hFile;
+       CWADARCHIVE *cOpenArc = (CWADARCHIVE *)cOpenFile->f->pParentArc;
+       if (cOpenFile->dwFilePointer >= cOpenFile->f->dwFullSize)
+               return 0;
+       if (cOpenFile->dwFilePointer + nNumberOfBytesToRead > cOpenFile->f->dwFullSize)
+               nNumberOfBytesToRead = cOpenFile->f->dwFullSize - cOpenFile->dwFilePointer;
+       unsigned long nBytesRead = nNumberOfBytesToRead;
+       if (cOpenFile->f->dwFlags & 1) {
+               if (!cOpenFile->f->pBuffer) {
+                       cOpenFile->f->pBuffer = (UInt8 *)malloc(cOpenFile->f->dwFullSize);
+                       UInt8 *compbuffer = (UInt8 *)malloc(cOpenFile->f->dwPackedSize);
+                       bool bReadOK = false;
+                       if (cOpenFile->f->pBuffer && compbuffer) {
+                               fseek(cOpenArc->pFile, cOpenFile->f->nOffset, SEEK_SET);
+                               if (fread(compbuffer, 1, cOpenFile->f->dwPackedSize, cOpenArc->pFile) == cOpenFile->f->dwPackedSize)
+                                       if (uncompress(cOpenFile->f->pBuffer, &nBytesRead, compbuffer, cOpenFile->f->dwPackedSize) == Z_OK)
+                                               bReadOK = true;
+                       }
+                       if (!bReadOK && cOpenFile->f->pBuffer) {
+                               free(cOpenFile->f->pBuffer);
+                               cOpenFile->f->pBuffer = 0;
+                               nBytesRead = 0;
+                       }
+                       if (compbuffer)
+                               free(compbuffer);
+               }
+               if (cOpenFile->f->pBuffer)
+                       memcpy(pBuffer, cOpenFile->f->pBuffer + cOpenFile->dwFilePointer, nNumberOfBytesToRead);
+       }
+       else {
+               fseek(cOpenArc->pFile, cOpenFile->f->nOffset + cOpenFile->dwFilePointer, SEEK_SET);
+               nBytesRead = fread(pBuffer, 1, nNumberOfBytesToRead, cOpenArc->pFile);
+       }
+
+       cOpenFile->dwFilePointer += nBytesRead;
+       return nBytesRead;
+}
+
+unsigned long CWadFindHeader(FILE *hFile)
+{
+       return CWadFindHeaderAndSize(hFile, 0);
+}
+
+unsigned long CWadFindHeaderAndSize(FILE *pFile, unsigned long *pnCwadEnd)
+{
+       if (!pFile) return -1;
+
+       if (fseek(pFile, 0, SEEK_END)) return -1;
+       long fsz = ftell(pFile);
+       UInt32 buffer[2];
+       long sep, i, offset;
+
+       if (pnCwadEnd) *pnCwadEnd = fsz;
+
+       fseek(pFile, 0, SEEK_SET);
+       if (fread(buffer, sizeof(UInt32), 1, pFile) < 1) return -1;
+       if (buffer[0] == ID_CWAD)
+               return 0;
+
+       if (fsz < 12)
+               return -1;
+
+       if (pnCwadEnd) *pnCwadEnd = fsz - 8;
+
+       fseek(pFile, -8, SEEK_END);
+       if (fread(buffer, sizeof(UInt32), 2, pFile) < 2) return -1;
+       if (buffer[0] == ID_CWAD) {
+               fseek(pFile, buffer[1], SEEK_SET);
+               if (fread(buffer, sizeof(UInt32), 1, pFile) < 1) return -1;
+               if (buffer[0] == ID_CWAD)
+                       return buffer[1];
+       }
+
+       if (fsz < 132)
+               return -1;
+
+       for (sep = fsz - 12; sep >= fsz - 132; sep -= 8) {
+               fseek(pFile, sep, SEEK_SET);
+               if (fread(buffer, sizeof(UInt32), 1, pFile) < 1) return -1;
+
+               if (buffer[0] == ID_SEP) {
+                       for (i = sep + 4; i < fsz; i += 8) {
+                               fseek(pFile, i, SEEK_SET);
+                               if (fread(buffer, sizeof(UInt32), 2, pFile) < 2) return -1;
+
+                               offset = buffer[0];
+                               if (pnCwadEnd) *pnCwadEnd = offset + buffer[1] - 8;
+                               fseek(pFile, offset + buffer[1] - 8, SEEK_SET);
+                               if (fread(buffer, sizeof(UInt32), 2, pFile) < 2) return -1;
+                               if (buffer[0] == ID_CWAD) {
+                                       fseek(pFile, offset + buffer[1], SEEK_SET);
+                                       if (fread(buffer, sizeof(UInt32), 1, pFile) < 1) return -1;
+                                       if (buffer[0] == ID_CWAD)
+                                               return offset + buffer[1];
+                               }
+                       }
+
+                       break;
+               }
+       }
+
+       return -1;
+}
+
+void CWadDecryptData(UInt8 *pBuffer, unsigned long nBufferLength)
+{
+       if (!pBuffer || nBufferLength == 0) return;
+       pBuffer += nBufferLength - 1;
+       UInt8 byCWadKey;
+       byCWadKey = (UInt8)(66 - (nBufferLength << 1));
+       for (unsigned long i = 0; i < nBufferLength; i++) {
+               pBuffer[0] ^= (UInt8)(byCWadKey + (i << 1));
+               pBuffer--;
+       }
+}
diff --git a/CwadLib.h b/CwadLib.h
new file mode 100644 (file)
index 0000000..60e34d7
--- /dev/null
+++ b/CwadLib.h
@@ -0,0 +1,29 @@
+#ifndef CWADLIB_INCLUDED
+#define CWADLIB_INCLUDED
+
+#include <tchar.h>
+
+#define CWAD_INFO_NUM_FILES       0x03 //Number of files in CWAD
+#define CWAD_INFO_SIZE            0x05 //Size of CWAD or uncompressed file
+#define CWAD_INFO_COMPRESSED_SIZE 0x06 //Size of compressed file
+#define CWAD_INFO_FLAGS           0x07 //File flags (compressed, etc.)
+#define CWAD_INFO_PARENT          0x08 //Handle of CWAD that file is in
+#define CWAD_INFO_POSITION        0x09 //Position of file pointer in files
+
+#define CWAD_FILE_BEGIN   0
+#define CWAD_FILE_CURRENT 1
+#define CWAD_FILE_END     2
+
+void *        CWadOpenArchive(const TCHAR *pszFileName);
+bool          CWadCloseArchive(void *hCWAD);
+unsigned long CWadGetArchiveInfo(void *hCWAD, int nInfoType);
+unsigned long CWadListFiles(void *hCWAD, char *pmszBuffer, unsigned long nBufferLength); // Returns required buffer size.  Strings are in multi string form. (null-terminated strings with an extra null after the last string)
+void *        CWadOpenFile(void *hCWAD, const char *pszFileName);
+bool          CWadCloseFile(void *hFile);
+unsigned long CWadGetFileSize(void *hFile);
+unsigned long CWadGetFileInfo(void *hFile, int nInfoType);
+unsigned long CWadSetFilePointer(void *hFile, long nDistanceToMove, int nMoveMethod);
+unsigned long CWadReadFile(void *hFile, void *pBuffer, unsigned long nNumberOfBytesToRead);
+unsigned long CWadFindHeader(FILE *pFile);
+
+#endif
diff --git a/Cwad_specs.txt b/Cwad_specs.txt
new file mode 100644 (file)
index 0000000..96f4090
--- /dev/null
@@ -0,0 +1,69 @@
+These structs are to demonstrate the layout of a CWAD file.   Note that they are not actual working structs.
+
+In C++:
+
+       struct CWAD {
+               char     IDTag[4] = "CWAD";
+               CWADFILE Files[];
+       };
+
+       struct CWADFILE {
+               DWORD dwPackedSize;
+               DWORD dwNameLength;
+               DWORD dwFullSize;
+               DWORD dwFlags;
+               char  lpFileName[dwNameLength];
+               BYTE  lpData[dwPackedSize];
+       };
+
+In VB:
+
+       Type CWAD
+               IDTag As String * 4 = "CWAD"
+               Files() as CWADFILE
+       End Type
+
+       Type CWADFILE
+               dwPackedSize As Long
+               dwNameLength As Long
+               dwFullSize As Long
+               dwFlags As Long
+               lpFileName As String * dwNameLength
+               lpData(dwPackedSize) As Byte
+       End Type
+
+At the beginning, there are 4 bytes, the string "CWAD".  After that there is a CWADFILE struct for each file until the end of the CWAD file.  After the 16 bytes for the header for each file is the filename, then the actual file data, then the next file header.
+
+If dwFlags is 0, the file is uncompressed.
+If it is 1, the file is compressed.
+
+Filenames are encrypted with a fairly simple encryption method.  Here is some code for decrypting them:
+
+In C++:
+
+void DecryptData(BYTE *lpBuffer, DWORD dwBufferLength)
+{
+       if (lpBuffer==0 || dwBufferLength==0) return;
+       lpBuffer += dwBufferLength - 1;
+       BYTE byCWadKey;
+       byCWadKey = (BYTE)(66 - (dwBufferLength << 1));
+       for (DWORD i=0;i<dwBufferLength;i++) {
+               lpBuffer[0] ^= (BYTE)(byCWadKey + (i << 1));
+               lpBuffer--;
+       }
+}
+
+In VB:
+
+Sub DecryptData(ByRef lpBuffer As String)
+       Dim byCWadKey As Byte, i As Long, n As Long
+       n = Len(lpBuffer)
+       byCWadKey = (66 - (n * 2)) Mod 256
+       For i = 0 To Len(lpBuffer) - 1
+               Mid(lpBuffer, n, 1) = Chr$(Asc(Mid$(lpBuffer, n, 1)) Xor ((byCWadKey + (i * 2)) Mod 256))
+               n = n - 1
+       Next i
+End Function
+
+The actual file data is compressed with zlib's compress function, so use zlib's decompress function to decompress the file data.  You may get zlib at http://www.gzip.org/zlib/
+
diff --git a/SFTypes.h b/SFTypes.h
new file mode 100644 (file)
index 0000000..a347a13
--- /dev/null
+++ b/SFTypes.h
@@ -0,0 +1,57 @@
+#ifndef SFTYPES_INCLUDED
+#define SFTYPES_INCLUDED
+
+#if defined(_WIN32) || defined(_WIN64)
+
+typedef signed char    Int8;
+typedef signed short   Int16;
+typedef signed long    Int32;
+typedef signed __int64 Int64;
+
+#ifdef _WIN64
+typedef signed __int64 IntPtr;
+#else
+typedef signed int     IntPtr;
+#endif
+
+typedef unsigned char    UInt8;
+typedef unsigned short   UInt16;
+typedef unsigned long    UInt32;
+typedef unsigned __int64 UInt64;
+
+#ifdef _WIN64
+typedef unsigned __int64 UIntPtr;
+#else
+typedef unsigned int     UIntPtr;
+#endif
+
+#else
+
+#include <stdint.h>
+
+typedef int8_t   Int8;
+typedef int16_t  Int16;
+typedef int32_t  Int32;
+typedef int64_t  Int64;
+typedef intptr_t IntPtr;
+
+typedef uint8_t   UInt8;
+typedef uint16_t  UInt16;
+typedef uint32_t  UInt32;
+typedef uint64_t  UInt64;
+typedef uintptr_t UIntPtr;
+
+#endif
+
+union IntConv {
+       Int8 i8[8];
+       UInt8 ui8[8];
+       Int16 i16[4];
+       UInt16 ui16[4];
+       Int32 i32[2];
+       UInt32 ui32[2];
+       Int64 i64;
+       UInt64 ui64;
+};
+
+#endif // #ifndef SFTYPES_INCLUDED