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}