📄 stormportmac.cpp.svn-base
字号:
/********************************************************************
*
* Description: implementation for StormLib - Macintosh port
*
* these are function wraps to execute Windows API calls
* as native Macintosh file calls (open/close/read/write/...)
* requires Mac OS X
*
* Derived from Marko Friedemann <marko.friedemann@bmx-chemnitz.de>
* StormPort.cpp for Linux
*
* Author: Daniel Chiaramello <daniel@chiaramello.net>
*
* Carbonized by: Sam Wilkins <swilkins1337@gmail.com>
*
********************************************************************/
#ifndef _WIN32 || _WIN64
#include "StormPort.h"
#include "StormLib.h"
// FUNCTIONS EXTRACTED FROM MOREFILE PACKAGE!!!
// FEEL FREE TO REMOVE THEM AND TO ADD THE ORIGINAL ONES!
/*****************************************************************************
* BEGIN OF MOREFILES COPY-PASTE
*****************************************************************************/
#ifdef __USEPRAGMAINTERNAL
#ifdef __MWERKS__
#pragma internal on
#endif
#endif
union TLongAnd4Bytes
{
unsigned char bytes[4];
unsigned long uvalue;
signed long svalue;
};
static OSErr FSGetFullPath(const FSRef *ref, UInt8 *fullPath, UInt32 fullPathLength)
{
OSErr result;
result = FSRefMakePath(ref, fullPath, fullPathLength);
return result;
}
static OSErr FSLocationFromFullPath(const void *fullPath, FSRef *ref)
{
OSErr result;
result = FSPathMakeRef((UInt8 *)fullPath, ref, NULL); // Create an FSRef from the path
return result;
}
/*****************************************************************************/
/*****************************************************************************/
static OSErr FSCreateCompat(const FSRef *parentRef, OSType creator, OSType fileType, const UniChar *fileName,
UniCharCount nameLength, FSRef *ref)
{
FSCatalogInfo theCatInfo;
OSErr theErr;
((FileInfo *)&theCatInfo.finderInfo)->fileCreator = creator;
((FileInfo *)&theCatInfo.finderInfo)->fileType = fileType;
((FileInfo *)&theCatInfo.finderInfo)->finderFlags = 0;
SetPt(&((FileInfo *)&theCatInfo.finderInfo)->location, 0, 0);
((FileInfo *)&theCatInfo.finderInfo)->reservedField = 0;
theErr = FSCreateFileUnicode(parentRef, nameLength, fileName, kFSCatInfoFinderInfo, &theCatInfo, ref, NULL);
return theErr;
}
/*****************************************************************************/
static OSErr FSOpenDFCompat(FSRef *ref, char permission, short *refNum)
{
HFSUniStr255 forkName;
OSErr theErr;
Boolean isFolder, wasChanged;
theErr = FSResolveAliasFile(ref, TRUE, &isFolder, &wasChanged);
if (theErr != noErr)
return theErr;
FSGetDataForkName(&forkName);
theErr = FSOpenFork(ref, forkName.length, forkName.unicode, permission, refNum);
return theErr;
}
/*****************************************************************************
* END OF MOREFILES COPY-PASTE
*****************************************************************************/
#pragma mark -
int globalerr;
/********************************************************************
* SwapLong
********************************************************************/
unsigned long SwapULong(unsigned long data)
{
// Apple provided function
uint32_t result;
__asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data));
return result;
/*
TLongAnd4Bytes Work;
unsigned char * value_as_4bytes = (unsigned char *)&value;
Work.bytes[0] = value_as_4bytes[3];
Work.bytes[1] = value_as_4bytes[2];
Work.bytes[2] = value_as_4bytes[1];
Work.bytes[3] = value_as_4bytes[0];
return Work.uvalue;
*/
}
long SwapLong(unsigned long data)
{
// Apple provided function
uint32_t result;
__asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data));
return (long)result;
/*
TLongAnd4Bytes Work;
unsigned char * value_as_4bytes = (unsigned char *)&value;
Work.bytes[0] = value_as_4bytes[3];
Work.bytes[1] = value_as_4bytes[2];
Work.bytes[2] = value_as_4bytes[1];
Work.bytes[3] = value_as_4bytes[0];
return Work.svalue;
*/
}
/********************************************************************
* SwapShort
********************************************************************/
unsigned short SwapUShort(unsigned short data)
{
// Apple provided function
uint16_t result;
__asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data));
return result;
}
short SwapShort(unsigned short data)
{
// Apple provided function
uint16_t result;
__asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&data), "m" (data));
return (short)result;
}
/********************************************************************
* ConvertUnsignedLongBuffer
********************************************************************/
void ConvertUnsignedLongBuffer(unsigned long *buffer, unsigned long nbLongs)
{
while (nbLongs-- > 0)
{
*buffer = SwapLong(*buffer);
buffer++;
}
}
/********************************************************************
* ConvertUnsignedShortBuffer
********************************************************************/
void ConvertUnsignedShortBuffer(unsigned short *buffer, unsigned long nbShorts)
{
while (nbShorts-- > 0)
{
*buffer = SwapShort(*buffer);
buffer++;
}
}
/********************************************************************
* ConvertTMPQShunt
********************************************************************/
void ConvertTMPQShunt(void *shunt)
{
TMPQShunt * theShunt = (TMPQShunt *)shunt;
theShunt->dwID = SwapULong(theShunt->dwID);
theShunt->dwUnknown = SwapULong(theShunt->dwUnknown);
theShunt->dwHeaderPos = SwapULong(theShunt->dwHeaderPos);
}
/********************************************************************
* ConvertTMPQHeader
********************************************************************/
void ConvertTMPQHeader(void *header)
{
TMPQHeader2 * theHeader = (TMPQHeader2 *)header;
theHeader->dwID = SwapULong(theHeader->dwID);
theHeader->dwHeaderSize = SwapULong(theHeader->dwHeaderSize);
theHeader->dwArchiveSize = SwapULong(theHeader->dwArchiveSize);
theHeader->wFormatVersion = SwapUShort(theHeader->wFormatVersion);
theHeader->wBlockSize = SwapUShort(theHeader->wBlockSize);
theHeader->dwHashTablePos = SwapULong(theHeader->dwHashTablePos);
theHeader->dwBlockTablePos = SwapULong(theHeader->dwBlockTablePos);
theHeader->dwHashTableSize = SwapULong(theHeader->dwHashTableSize);
theHeader->dwBlockTableSize = SwapULong(theHeader->dwBlockTableSize);
if(theHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2)
{
DWORD dwTemp = theHeader->ExtBlockTablePos.LowPart;
theHeader->ExtBlockTablePos.LowPart = theHeader->ExtBlockTablePos.HighPart;
theHeader->ExtBlockTablePos.HighPart = dwTemp;
theHeader->ExtBlockTablePos.LowPart = SwapULong(theHeader->ExtBlockTablePos.LowPart);
theHeader->ExtBlockTablePos.HighPart = SwapULong(theHeader->ExtBlockTablePos.HighPart);
theHeader->wHashTablePosHigh = SwapUShort(theHeader->wHashTablePosHigh);
theHeader->wBlockTablePosHigh = SwapUShort(theHeader->wBlockTablePosHigh);
}
}
/********************************************************************
* ConvertTMPQHash
********************************************************************/
void ConvertHashTable(void *hashtable, DWORD nHashEntries)
{
TMPQHash * theHash = (TMPQHash *)hashtable;
USHORT lcLocale;
for(DWORD i = 0; i < nHashEntries; i++, theHash++)
{
lcLocale = theHash->lcLocale;
theHash->lcLocale = theHash->wPlatform;
theHash->wPlatform = lcLocale;
}
}
#pragma mark -
/********************************************************************
* SetLastError
********************************************************************/
void SetLastError(int err)
{
globalerr = err;
}
/********************************************************************
* GetLastError
********************************************************************/
int GetLastError()
{
return globalerr;
}
/********************************************************************
* ErrString
********************************************************************/
char *ErrString(int err)
{
switch (err)
{
case ERROR_INVALID_FUNCTION:
return "function not implemented";
case ERROR_FILE_NOT_FOUND:
return "file not found";
case ERROR_ACCESS_DENIED:
return "access denied";
case ERROR_NOT_ENOUGH_MEMORY:
return "not enough memory";
case ERROR_BAD_FORMAT:
return "bad format";
case ERROR_NO_MORE_FILES:
return "no more files";
case ERROR_HANDLE_EOF:
return "access beyound EOF";
case ERROR_HANDLE_DISK_FULL:
return "no space left on device";
case ERROR_INVALID_PARAMETER:
return "invalid parameter";
case ERROR_DISK_FULL:
return "no space left on device";
case ERROR_ALREADY_EXISTS:
return "file exists";
case ERROR_CAN_NOT_COMPLETE:
return "operation cannot be completed";
case ERROR_INSUFFICIENT_BUFFER:
return "insufficient buffer";
default:
return "unknown error";
}
}
#pragma mark -
/********************************************************************
* GetTempPath - returns a '/' or ':'-terminated path
* szTempLength: length for path
* szTemp: file path
********************************************************************/
void GetTempPath(DWORD szTempLength, char * szTemp) // I think I'll change this to use FSRefs.
{
FSRef theFSRef;
OSErr theErr = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, kCreateFolder, &theFSRef);
if (theErr == noErr)
{
theErr = FSGetFullPath(&theFSRef, (UInt8 *)szTemp, MAX_PATH);
if (theErr != noErr)
szTemp[0] = '\0';
}
else
szTemp[0] = '\0';
strcat(szTemp, "/");
SetLastError(theErr);
}
/********************************************************************
* GetTempFileName
* lpTempFolderPath: the temporary folder path, terminated by "/"
* lpFileName: a file name base
* something: unknown
* szLFName: the final path, built from the path, the file name and a random pattern
********************************************************************/
void GetTempFileName(const char * lpTempFolderPath, const char * lpFileName, DWORD something, char * szLFName)
{
#pragma unused (something)
char tmp[2] = "A";
while (true)
{
HANDLE fHandle;
strcpy(szLFName, lpTempFolderPath);
strcat(szLFName, lpFileName);
strcat(szLFName, tmp);
if ((fHandle = CreateFile(szLFName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
// OK we found it!
break;
CloseHandle(fHandle);
tmp[0]++;
}
}
/********************************************************************
* DeleteFile
* lpFileName: file path
********************************************************************/
BOOL DeleteFile(const char * lpFileName)
{
OSErr theErr;
FSRef theFileRef;
theErr = FSLocationFromFullPath(lpFileName, &theFileRef);
if (theErr != noErr)
{
SetLastError(theErr);
return FALSE;
}
theErr = FSDeleteObject(&theFileRef);
SetLastError(theErr);
return theErr == noErr;
}
/********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -