Subversion Repositories freemyipod

Rev

Rev 654 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
653 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emCORE is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "emcorelib.h"
25
#include "export/libmkfat32.h"
26
 
27
 
28
struct libmkfat32_api apitable =
29
{
30
    .mkfat32 = mkfat32
31
};
32
 
33
 
34
EMCORE_LIB_HEADER(LIBMKFAT32_IDENTIFIER, LIBMKFAT32_API_VERSION, LIBMKFAT32_MIN_API_VERSION,
35
                  NULL, NULL, apitable)
36
 
37
 
38
int mkfat32(int volume, int startsector, int totalsectors, int sectorsize, int secperclus,
39
            const char* label, void* statususer, void (*statusinit)(void* user, int max),
40
            void (*statuscallback)(void* user, int current))
41
{
42
    uint32_t i, j;
43
    uint32_t rootdirclus = 2;
44
    uint32_t fatsectors = 1;
45
    uint32_t oldfatsectors = 0;
46
    uint32_t clustercount;
47
    uint32_t reserved = 2;
48
    disk_unmount(volume);
49
    while (fatsectors != oldfatsectors)
50
    {
51
        oldfatsectors = fatsectors;
52
        clustercount = (totalsectors - fatsectors - reserved) / secperclus;
53
        fatsectors = (clustercount * 4 + sectorsize + 8)  / sectorsize;
54
    }
55
    uint32_t database = fatsectors + reserved;
56
    uint32_t clusoffset = 0;
57
    uint32_t* buf = memalign(0x10, 32 * sectorsize);
58
    memset(buf, 0, sectorsize);
59
    memcpy(buf, "\xeb\x58\x00MSWIN5.0", 0xb);
60
    ((uint8_t*)buf)[0xb] = sectorsize & 0xff;
61
    ((uint8_t*)buf)[0xc] = sectorsize >> 8;
62
    ((uint8_t*)buf)[0xd] = secperclus;
63
    ((uint16_t*)buf)[7] = reserved;
64
    memcpy(&((uint8_t*)buf)[0x10], "\x01\0\0\0\0\xf8\0\0\x3f\0\xff", 0xb);
65
    buf[8] = startsector;
66
    buf[8] = totalsectors;
67
    buf[9] = fatsectors;
68
    buf[0xb] = rootdirclus + clusoffset;
69
    ((uint16_t*)buf)[0x18] = 1;
70
    ((uint8_t*)buf)[0x40] = 0x80;
71
    ((uint8_t*)buf)[0x42] = 0x29;
72
    memcpy(&((uint8_t*)buf)[0x47], label, 0xb);
73
    memcpy(&((uint8_t*)buf)[0x52], "FAT32   ", 8);
74
    ((uint16_t*)buf)[0xff] = 0xaa55;
75
    PASS_RC(storage_write_sectors_md(volume, startsector, 1, buf), 2, 0);
76
    memset(buf, 0, sectorsize);
77
    buf[0] = 0x41615252;
78
    buf[0x79] = 0x61417272;
79
    buf[0x7a] = clustercount - 1;
80
    buf[0x7b] = 2;
81
    buf[0x7f] = 0xaa550000;
82
    PASS_RC(storage_write_sectors_md(volume, startsector + 1, 1, buf), 2, 1);
83
    statusinit(statususer, fatsectors);
84
    uint32_t cursect = 0;
85
    for (i = 0; i < fatsectors; i += 32)
86
    {
87
        memset(buf, 0, 32 * sectorsize);
88
        if (!i) memcpy(buf, "\xf8\xff\xff\x0f\xff\xff\xff\xff\xff\xff\xff\x0f", 12);
89
        PASS_RC(storage_write_sectors_md(volume, startsector + reserved + i,
90
                                         MIN(fatsectors - i, 32), buf), 2, 2);
91
        statuscallback(statususer, i);
92
    }
93
    memset(buf, 0, secperclus * sectorsize);
94
    memcpy(buf, label, 11);
95
    ((uint8_t*)buf)[0xc] = 0x80;
96
    PASS_RC(storage_write_sectors_md(volume, startsector + database, secperclus, buf), 2, 3);
97
    free(buf);
98
    disk_mount(volume);
99
}