summaryrefslogtreecommitdiff
path: root/com32/gpllib/disk/mbrs.c
blob: 6150fcf43c8c0ca3d8cce44cec13bd76b8a66a13 (plain)
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
/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2009 Pierre-Alexandre Meyer
 *
 *   This file is part of Syslinux, and is made available under
 *   the terms of the GNU General Public License version 2.
 *
 * ----------------------------------------------------------------------- */

#include <disk/common.h>
#include <disk/geom.h>
#include <disk/read.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/**
 * get_mbr_string - return a string describing the boot code
 * @label:		first four bytes of the MBR
 * @buffer:		pre-allocated buffer
 * @buffer_size:	@buffer size
 **/
void get_mbr_string(const uint32_t label, char *buffer, const int buffer_size)
{
    /* 2 bytes are usually enough to identify the MBR */
    uint16_t s_label = label >> 16;

    switch (s_label) {
    case 0x0000:
    case 0xfabe:
	strlcpy(buffer, "No bootloader", buffer_size - 1);
	break;
    case 0x0ebe:
	strlcpy(buffer, "ThinkPad", buffer_size - 1);
	break;
    case 0x31c0:
	strlcpy(buffer, "Acer 3", buffer_size - 1);
	break;
    case 0x33c0:
	/* We need more than 2 bytes */
	if (((label >> 8) & 0xff) == 0x8e)
	    strlcpy(buffer, "Windows", buffer_size - 1);
	else if (((label >> 8) & 0xff) == 0x90)
	    strlcpy(buffer, "DiskCryptor", buffer_size - 1);
	else if (((label >> 8) & 0xff) == 0xfa)
	    strlcpy(buffer, "Syslinux", buffer_size - 1);
	else
	    strlcpy(buffer, "Unknown mbr", buffer_size - 1);
	break;
    case 0x33ed:
	strlcpy(buffer, "Syslinux ISOhybrid", buffer_size - 1);
	break;
    case 0x33ff:
	strlcpy(buffer, "HP/Gateway", buffer_size - 1);
	break;
    case 0xb800:
	strlcpy(buffer, "PloP", buffer_size - 1);
	break;
    case 0xea05:
	strlcpy(buffer, "XOSL", buffer_size - 1);
	break;
    case 0xea1e:
	strlcpy(buffer, "Truecrypt Boot Loader", buffer_size - 1);
	break;
    case 0xeb04:
	strlcpy(buffer, "Solaris", buffer_size - 1);
	break;
    case 0xeb31:
	strlcpy(buffer, "Paragon", buffer_size - 1);
	break;
    case 0xeb48:
	strlcpy(buffer, "Grub", buffer_size - 1);
	break;
    case 0xeb4c:
	strlcpy(buffer, "Grub2 (v1.96)", buffer_size - 1);
	break;
    case 0xeb63:
	strlcpy(buffer, "Grub2 (v1.97)", buffer_size - 1);
	break;
    case 0xeb5e:
	/* We need more than 2 bytes */
	if (((label >> 8) & 0xff) == 0x00)
	    strlcpy(buffer, "fbinst", buffer_size - 1);
	else if (((label >> 8) & 0xff) == 0x80)
	    strlcpy(buffer, "Grub4Dos", buffer_size - 1);
	else if (((label >> 8) & 0xff) == 0x90)
	    strlcpy(buffer, "WEE", buffer_size - 1);
	else
	    strlcpy(buffer, "Unknown mbr", buffer_size - 1);
	break;
    case 0xfa31:
	/* We need more than 2 bytes */
	if (((label >> 8) & 0xff) == 0xc0)
	    strlcpy(buffer, "Syslinux", buffer_size - 1);
	else if (((label >> 8) & 0xff) == 0xc9)
	    strlcpy(buffer, "Master Boot LoaDeR", buffer_size - 1);
	else
	    strlcpy(buffer, "Unknown mbr", buffer_size - 1);
	break;
    case 0xfa33:
	strlcpy(buffer, "MS-DOS 3.30 through Windows 95 (A)", buffer_size - 1);
	break;
    case 0xfab8:
	strlcpy(buffer, "FreeDOS (eXtended FDisk)", buffer_size - 1);
	break;
    case 0xfaeb:
	strlcpy(buffer, "Lilo", buffer_size - 1);
	break;
    case 0xfc31:
	strlcpy(buffer, "Testdisk", buffer_size - 1);
	break;
    case 0xfc33:
	strlcpy(buffer, "GAG", buffer_size - 1);
	break;
    case 0xfceb:
	strlcpy(buffer, "BootIT NG", buffer_size - 1);
	break;
    default:
	strlcpy(buffer, "Unknown mbr", buffer_size - 1);
	break;
    }

    buffer[buffer_size - 1] = '\0';
}

/**
 * get_mbr_id - return the first four bytes of the MBR
 * @d:		driveinfo struct describing the drive
 **/
uint32_t get_mbr_id(const struct driveinfo *d)
{
    char mbr[SECTOR * sizeof(char)];

    if (read_mbr(d->disk, &mbr) == -1)
	return -1;
    else {
	uint32_t mbr_id;
	/* Reverse the opcodes */
	mbr_id = (*(uint8_t *) (mbr + 3));
	mbr_id += (*(uint8_t *) (mbr + 2) << 8);
	mbr_id += (*(uint8_t *) (mbr + 1) << 16);
	mbr_id += (*(uint8_t *) mbr) << 24;
	return mbr_id;
    }
}