-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathhfsunhide.c
149 lines (144 loc) · 3.42 KB
/
hfsunhide.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* Thomas BERNARD */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hfscommon.h"
void writeu16(unsigned char * p, uint16_t i)
{
p[0] = (i >> 8) & 0xff;
p[1] = i & 0xff;
}
/* return :
0 OK
1 command line arguments error
2 cannot open iso file
3 no HFS/HFS+ partition found in iso file
4 HFS+ header node not found
5 cannot open iso file for writing
6 saving failed
42 Not found
43 dont need patching
*/
int main(int argc, char * * argv)
{
FILE * f;
const char * isofile = NULL;
const char * path = NULL;
int i;
int doit = 0;
int verbose = 0;
unsigned char * catalog = NULL;
int found = 0;
int need_patching = 0;
struct find_infos infos;
int ret = 0;
for(i = 1; i < argc; i++) {
if(strcmp(argv[i], "-v")==0)
verbose++;
else if(strcmp(argv[i], "--doit")==0)
doit = 1;
else if(isofile == NULL)
isofile = argv[i];
else if(path == NULL)
path = argv[i];
else {
fprintf(stderr, "unrecognized argument : %s\n", argv[i]);
return 1;
}
}
if(isofile == NULL || path == NULL) {
fprintf(stderr, "Usage: %s [--doit] [-v] <image.iso> path/.../file.txt\n", argv[0]);
return 1;
}
printf("isofile=%s path=%s\n", isofile, path);
f = fopen(isofile, "rb");
if(f == NULL) {
fprintf(stderr, "cannot open %s for reading\n", isofile);
return 2;
}
read_partition_map(f);
if(hfs_part_sector == 0 && hfs_part_sector_count == 0) {
printf("HFS/HFS+ partition not found\n");
fclose(f);
return 3;
} else {
const char * curpath;
char pathelt[256];
uint32_t folder_id;
read_hfs_volume_header(f);
//read_catalog(f);
catalog = load_catalog(f);
if(!print_node(catalog)) { /* header node */
free(catalog);
return 4;
}
/* find path/.../file.txt */
curpath = path;
folder_id = 2; /* root id */
do {
char * p;
size_t len;
p = strchr(curpath, '/');
if(p) {
len = p - curpath;
if(len >= sizeof(pathelt))
len = sizeof(pathelt) - 1;
memcpy(pathelt, curpath, len);
pathelt[len] = '\0';
curpath = p + 1;
} else {
strncpy(pathelt, curpath, sizeof(pathelt));
curpath = NULL;
}
if(!hfs_find(catalog, folder_id, pathelt, &infos)) {
/* not found */
break;
}
if(curpath) {
folder_id = infos.folder_id;
printf("Folder %s found : id=%u\n", pathelt, folder_id);
} else {
printf("Folder/file %s found ! flags=%04X\n",
path, readu16(infos.p + 56));
found = 1;
if(readu16(infos.p + 56) & 0x4000)
need_patching = 1;
}
} while(curpath && !found);
}
fclose(f);
if(!found) {
fprintf(stderr, "Folder/file %s NOT FOUND !\n", path);
ret = 42;
} else if(!need_patching) {
fprintf(stderr, "%s doesn't need patching\n", isofile);
ret = 43;
}
// kIsInvisible = 0x4000, /* Files and folders */
if(doit && found && need_patching) {
uint16_t HFSflags, newHFSflags;
printf("unhidding %s\n", path);
HFSflags = readu16(infos.p + 56);
newHFSflags = HFSflags & ~0x4000;
printf("flags %04X => %04X (offset %Xh in catalog)\n",
HFSflags, newHFSflags, (unsigned)(infos.p + 56 - catalog));
writeu16(infos.p + 56, newHFSflags);
printf("writing patched catalog\n");
f = fopen(isofile, "r+b");
if(f == NULL) {
fprintf(stderr, "cannot open %s for writing\n", isofile);
ret = 5;
} else {
if(save_catalog(f, catalog)) {
printf("SUCCESS\n");
ret = 0;
} else {
fprintf(stderr, "save_catalog() failed\n");
ret = 6;
}
}
fclose(f);
}
free(catalog);
return ret;
}