static void *HHA_openArchive(const char *name, int forWriting) { PHYSFS_sint64 modtime = __PHYSFS_platformGetLastModTime(name); HHAinfo *info = (HHAinfo *) allocator.Malloc(sizeof (HHAinfo)); BAIL_IF_MACRO(info == NULL, ERR_OUT_OF_MEMORY, 0); memset(info, '\0', sizeof (HHAinfo)); info->filename = (char *) allocator.Malloc(strlen(name) + 1); GOTO_IF_MACRO(!info->filename, ERR_OUT_OF_MEMORY, HHA_openArchive_failed); if (!HHA_load_entries(name, forWriting, info)) goto HHA_openArchive_failed; strcpy(info->filename, name); info->last_mod_time = modtime; return(info); HHA_openArchive_failed: if (info != NULL) { if (info->filename != NULL) allocator.Free(info->filename); if (info->entries != NULL) allocator.Free(info->entries); allocator.Free(info); } /* if */ return(NULL); } /* HHA_openArchive */
PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists) { PHYSFS_Io *retval = NULL; UNPKinfo *info = (UNPKinfo *) opaque; UNPKfileinfo *finfo = NULL; int isdir = 0; UNPKentry *entry = findEntry(info, fnm, &isdir); *fileExists = (entry != NULL); GOTO_IF_MACRO(isdir, PHYSFS_ERR_NOT_A_FILE, UNPK_openRead_failed); GOTO_IF_MACRO(!entry, ERRPASS, UNPK_openRead_failed); retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io)); GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed); finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo)); GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed); finfo->io = info->io->duplicate(info->io); GOTO_IF_MACRO(!finfo->io, ERRPASS, UNPK_openRead_failed); if (!finfo->io->seek(finfo->io, entry->startPos)) goto UNPK_openRead_failed; finfo->curPos = 0; finfo->entry = entry; memcpy(retval, &UNPK_Io, sizeof (*retval)); retval->opaque = finfo; return retval; UNPK_openRead_failed: if (finfo != NULL) { if (finfo->io != NULL) finfo->io->destroy(finfo->io); allocator.Free(finfo); } /* if */ if (retval != NULL) allocator.Free(retval); return NULL; } /* UNPK_openRead */
static UNPKentry *slbLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount) { UNPKentry *entries = NULL; UNPKentry *entry = NULL; entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount); BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL); for (entry = entries; fileCount > 0; fileCount--, entry++) { char *ptr; /* don't include the '\' in the beginning */ char backslash; GOTO_IF_MACRO(!__PHYSFS_readAll(io, &backslash, 1), ERRPASS, failed); GOTO_IF_MACRO(backslash != '\\', ERRPASS, failed); /* read the rest of the buffer, 63 bytes */ GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->name, 63), ERRPASS, failed); entry->name[63] = '\0'; /* in case the name lacks the null terminator */ /* convert backslashes */ for (ptr = entry->name; *ptr; ptr++) { if (*ptr == '\\') *ptr = '/'; } /* for */ GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->startPos, 4), ERRPASS, failed); entry->startPos = PHYSFS_swapULE32(entry->startPos); GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->size, 4), ERRPASS, failed); entry->size = PHYSFS_swapULE32(entry->size); } /* for */ return entries; failed: allocator.Free(entries); return NULL; } /* slbLoadEntries */
char *__PHYSFS_platformCalcUserDir(void) { typedef BOOL (WINAPI *fnGetUserProfDirW)(HANDLE, LPWSTR, LPDWORD); fnGetUserProfDirW pGetDir = NULL; HANDLE lib = NULL; HANDLE accessToken = NULL; /* Security handle to process */ char *retval = NULL; lib = LoadLibraryA("userenv.dll"); BAIL_IF_MACRO(!lib, errcodeFromWinApi(), NULL); pGetDir=(fnGetUserProfDirW) GetProcAddress(lib,"GetUserProfileDirectoryW"); GOTO_IF_MACRO(!pGetDir, errcodeFromWinApi(), done); if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &accessToken)) GOTO_MACRO(errcodeFromWinApi(), done); else { DWORD psize = 0; WCHAR dummy = 0; LPWSTR wstr = NULL; BOOL rc = 0; /* * Should fail. Will write the size of the profile path in * psize. Also note that the second parameter can't be * NULL or the function fails. */ rc = pGetDir(accessToken, &dummy, &psize); assert(!rc); /* !!! FIXME: handle this gracefully. */ (void) rc; /* Allocate memory for the profile directory */ wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR)); if (wstr != NULL) { if (pGetDir(accessToken, wstr, &psize)) { /* Make sure it ends in a dirsep. We allocated +1 for this. */ if (wstr[psize - 2] != '\\') { wstr[psize - 1] = '\\'; wstr[psize - 0] = '\0'; } /* if */ retval = unicodeToUtf8Heap(wstr); } /* if */ __PHYSFS_smallFree(wstr); } /* if */ CloseHandle(accessToken); } /* if */ done: FreeLibrary(lib); return retval; /* We made it: hit the showers. */ } /* __PHYSFS_platformCalcUserDir */
static PHYSFS_Io *UNPK_duplicate(PHYSFS_Io *_io) { UNPKfileinfo *origfinfo = (UNPKfileinfo *) _io->opaque; PHYSFS_Io *io = NULL; PHYSFS_Io *retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io)); UNPKfileinfo *finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo)); GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_duplicate_failed); GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_duplicate_failed); io = origfinfo->io->duplicate(origfinfo->io); if (!io) goto UNPK_duplicate_failed; finfo->io = io; finfo->entry = origfinfo->entry; finfo->curPos = 0; memcpy(retval, _io, sizeof (PHYSFS_Io)); retval->opaque = finfo; return retval; UNPK_duplicate_failed: if (finfo != NULL) allocator.Free(finfo); if (retval != NULL) allocator.Free(retval); if (io != NULL) io->destroy(io); return NULL; } /* UNPK_duplicate */