⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stormportmac.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/********************************************************************
*
* 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 + -