all repos — mgba @ 67905d281bfecbb06f51f2ca5ac939df378734a5

mGBA Game Boy Advance Emulator

src/platform/windows/vfs-w32.c (view raw)

  1/* Copyright (c) 2013-2016 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "util/vfs.h"
  7
  8#include "util/string.h"
  9
 10static bool _vdwClose(struct VDir* vd);
 11static void _vdwRewind(struct VDir* vd);
 12static struct VDirEntry* _vdwListNext(struct VDir* vd);
 13static struct VFile* _vdwOpenFile(struct VDir* vd, const char* path, int mode);
 14static struct VDir* _vdwOpenDir(struct VDir* vd, const char* path);
 15static bool _vdwDeleteFile(struct VDir* vd, const char* path);
 16
 17static const char* _vdweName(struct VDirEntry* vde);
 18static enum VFSType _vdweType(struct VDirEntry* vde);
 19
 20struct VDirW32;
 21struct VDirEntryW32 {
 22	struct VDirEntry d;
 23	WIN32_FIND_DATA ffData;
 24};
 25
 26struct VDirW32 {
 27	struct VDir d;
 28	HANDLE handle;
 29	struct VDirEntryW32 vde;
 30	char* path;
 31};
 32
 33struct VDir* VDirOpen(const char* path) {
 34	if (!path || !path[0]) {
 35		return 0;
 36	}
 37	char name[MAX_PATH];
 38	_snprintf(name, sizeof(name), "%s\\*", path);
 39	WIN32_FIND_DATA ffData;
 40	HANDLE handle = FindFirstFile(name, &ffData);
 41	if (handle == INVALID_HANDLE_VALUE) {
 42		return 0;
 43	}
 44
 45	struct VDirW32* vd = malloc(sizeof(struct VDirW32));
 46	if (!vd) {
 47		FindClose(handle);
 48		return 0;
 49	}
 50
 51	vd->d.close = _vdwClose;
 52	vd->d.rewind = _vdwRewind;
 53	vd->d.listNext = _vdwListNext;
 54	vd->d.openFile = _vdwOpenFile;
 55	vd->d.openDir = _vdwOpenDir;
 56	vd->d.deleteFile = _vdwDeleteFile;
 57	vd->handle = handle;
 58	vd->path = _strdup(path);
 59
 60	vd->vde.d.name = _vdweName;
 61	vd->vde.d.type = _vdweType;
 62	vd->vde.ffData = ffData;
 63
 64	return &vd->d;
 65}
 66
 67bool _vdwClose(struct VDir* vd) {
 68	struct VDirW32* vdw = (struct VDirW32*) vd;
 69	FindClose(vdw->handle);
 70	free(vdw);
 71	return true;
 72}
 73
 74void _vdwRewind(struct VDir* vd) {
 75	struct VDirW32* vdw = (struct VDirW32*) vd;
 76	FindClose(vdw->handle);
 77	char name[MAX_PATH];
 78	_snprintf(name, sizeof(name), "%s\\*", vdw->path);
 79	vdw->handle = FindFirstFile(name, &vdw->vde.ffData);
 80}
 81
 82struct VDirEntry* _vdwListNext(struct VDir* vd) {
 83	struct VDirW32* vdw = (struct VDirW32*) vd;
 84	if (FindNextFile(vdw->handle, &vdw->vde.ffData)) {
 85		return &vdw->vde.d;
 86	}
 87
 88	return 0;
 89}
 90
 91struct VFile* _vdwOpenFile(struct VDir* vd, const char* path, int mode) {
 92	struct VDirW32* vdw = (struct VDirW32*) vd;
 93	if (!path) {
 94		return 0;
 95	}
 96	const char* dir = vdw->path;
 97	char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2));
 98	sprintf(combined, "%s\\%s", dir, path);
 99
100	struct VFile* file = VFileOpen(combined, mode);
101	free(combined);
102	return file;
103}
104
105struct VDir* _vdwOpenDir(struct VDir* vd, const char* path) {
106	struct VDirW32* vdw = (struct VDirW32*) vd;
107	if (!path) {
108		return 0;
109	}
110	const char* dir = vdw->path;
111	char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2));
112	sprintf(combined, "%s\\%s", dir, path);
113
114	struct VDir* vd2 = VDirOpen(combined);
115	if (!vd2) {
116		vd2 = VDirOpenArchive(combined);
117	}
118	free(combined);
119	return vd2;
120}
121
122bool _vdwDeleteFile(struct VDir* vd, const char* path) {
123	struct VDirW32* vdw = (struct VDirW32*) vd;
124	if (!path) {
125		return 0;
126	}
127	const char* dir = vdw->path;
128	char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2));
129	sprintf(combined, "%s\\%s", dir, path);
130
131	bool ret = DeleteFile(combined);
132	free(combined);
133	return ret;
134}
135
136const char* _vdweName(struct VDirEntry* vde) {
137	struct VDirEntryW32* vdwe = (struct VDirEntryW32*) vde;
138	return vdwe->ffData.cFileName;
139}
140
141static enum VFSType _vdweType(struct VDirEntry* vde) {
142	struct VDirEntryW32* vdwe = (struct VDirEntryW32*) vde;
143	if (vdwe->ffData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
144		return VFS_DIRECTORY;
145	}
146	return VFS_FILE;
147}