Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision cbd640572786d277a31b5a1f8f88967e8962afd4)
+++ uspace/lib/c/Makefile	(revision 7570e80086a542f15630c4997dbb37e9720c123f)
@@ -66,4 +66,5 @@
 	generic/cap.c \
 	generic/cfg.c \
+	generic/checksum.c \
 	generic/clipboard.c \
 	generic/devman.c \
Index: uspace/lib/gpt/libgpt.c
===================================================================
--- uspace/lib/gpt/libgpt.c	(revision cbd640572786d277a31b5a1f8f88967e8962afd4)
+++ uspace/lib/gpt/libgpt.c	(revision 7570e80086a542f15630c4997dbb37e9720c123f)
@@ -38,9 +38,22 @@
  */
 
+#include <ipc/bd.h>
+#include <async.h>
+#include <stdio.h>
+#include <block.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <byteorder.h>
 #include <checksum.h>
-#include <errno.h>
 #include <mem.h>
 
 #include "libgpt.h"
+
+static int load_and_check_header(service_id_t handle, aoff64_t addr, size_t b_size, gpt_header_t * header);
+static gpt_parts_t * alloc_part_array(uint32_t num);
+static int extend_part_array(gpt_parts_t * p);
+static int reduce_part_array(gpt_parts_t * p);
+static long long nearest_larger_int(double a);
 
 /** Read GPT from specific device
@@ -66,5 +79,5 @@
 	}
 	
-	gpt->header_lba = malloc(b_size);// We might need only sizeof(gpt_header_t),
+	gpt->raw_data = malloc(b_size);// We might need only sizeof(gpt_header_t),
 	if (gpt == NULL) {				// but we should follow specs and have 
 		free(gpt);					// zeroes through all the rest of the block
@@ -74,5 +87,5 @@
 	
 	
-	rc = load_and_check_header(handle, GPT_HDR_BA, gpt->header_lba);
+	rc = load_and_check_header(dev_handle, GPT_HDR_BA, b_size, gpt->raw_data);
 	if (rc == EBADCHECKSUM || rc == EINVAL) {
 		aoff64_t n_blocks;
@@ -83,5 +96,5 @@
 		}
 		
-		rc = load_and_check_header(handle, n_blocks - 1, gpt->header_lba);
+		rc = load_and_check_header(dev_handle, n_blocks - 1, b_size, gpt->raw_data);
 		if (rc == EBADCHECKSUM || rc == EINVAL) {
 			errno = rc;
@@ -90,4 +103,6 @@
 	}
 	
+	gpt->device = dev_handle;
+	
 	return gpt;
 
@@ -103,11 +118,12 @@
  * @return				0 on success, libblock error code otherwise
  */
-int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle)
+int gpt_write_gpt_header(gpt_t * gpt, service_id_t dev_handle)
 {
 	int rc;
 	size_t b_size;
 	
-	header->raw_data->header_crc32 = 0;
-	header->raw_data->header_crc32 = compute_crc32(header, header->header_size);
+	gpt->raw_data->header_crc32 = 0;
+	gpt->raw_data->header_crc32 = compute_crc32((uint8_t *) gpt->raw_data,
+					uint32_t_le2host(gpt->raw_data->header_size));
 	
 	rc = block_get_bsize(dev_handle, &b_size);
@@ -120,5 +136,5 @@
 	
 	/* Write to main GPT header location */
-	rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, header->raw_data);
+	rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, gpt->raw_data);
 	if (rc != EOK)
 		block_fini(dev_handle);
@@ -131,5 +147,6 @@
 	
 	/* Write to backup GPT header location */
-	rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
+	//FIXME: those idiots thought it would be cool to have these fields in reverse order...
+	rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, gpt->raw_data);
 	block_fini(dev_handle);
 	if (rc != EOK)
@@ -147,9 +164,10 @@
 gpt_parts_t * gpt_read_partitions(gpt_t * gpt)
 {
-	int i;
+	int rc;
+	unsigned int i;
 	gpt_parts_t * res;
-	uint32_t num_ent = uint32_t_le2host(gpt->header.num_entries);
-	uint32_t ent_size = uint32_t_le2host(gpt->header.entry_size);
-	uint64_t ent_lba = uint64_t_le2host(gpt->header.entry_lba);
+	uint32_t num_ent = uint32_t_le2host(gpt->raw_data->num_entries);
+	uint32_t ent_size = uint32_t_le2host(gpt->raw_data->entry_size);
+	uint64_t ent_lba = uint64_t_le2host(gpt->raw_data->entry_lba);
 	
 	res = alloc_part_array(num_ent);
@@ -162,5 +180,5 @@
 	 *  - we don't need more bytes
 	 *  - the size of GPT partition entry can be different to 128 bytes */
-	rc = block_init(EXCHANGE_SERIALIZE, dev_handle, sizeof(gpt_entry_t));
+	rc = block_init(EXCHANGE_SERIALIZE, gpt->device, sizeof(gpt_entry_t));
 	if (rc != EOK) {
 		gpt_free_partitions(res);
@@ -200,7 +218,12 @@
 	}
 	
-	uint32_t crc = compute_crc32(res->part_array, res->num_ent * sizeof(gpt_entry_t));
-	
-	if(gpt->raw_data.pe_array_crc32 != crc)
+	/* FIXME: so far my boasting about variable partition entry size
+	 * will not work. The CRC32 checksums will be different.
+	 * This can't be fixed easily - we'd have to run the checksum
+	 * on all of the partition entry array.
+	 */
+	uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->num_ent * sizeof(gpt_entry_t));
+	
+	if(uint32_t_le2host(gpt->raw_data->pe_array_crc32) != crc)
 	{
 		gpt_free_partitions(res);
@@ -214,15 +237,15 @@
 /** Write GPT and partitions to device
  * @param parts			partition list to be written
- * @param mbr			MBR to be written with 'parts' partitions
+ * @param header		GPT header belonging to the 'parts' partitions
  * @param dev_handle	device to write the data to
  * 
  * @return				returns EOK on succes, specific error code otherwise
  */
-int gpt_write_partitions(gpt_parts_t * parts, gpt_t * header, service_id_t dev_handle)
-{
-	int i;
+int gpt_write_partitions(gpt_parts_t * parts, gpt_t * gpt, service_id_t dev_handle)
+{
+	int rc;
 	size_t b_size;
 	
-	header->raw_data->pe_array_crc32 = compute_crc32(parts->part_array, parts->num_ent * header->raw_data->entry_size);
+	gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->num_ent * gpt->raw_data->entry_size);
 	
 	rc = block_get_bsize(dev_handle, &b_size);
@@ -235,6 +258,6 @@
 	
 	/* Write to main GPT partition array location */
-	rc = block_write_direct(dev_handle, uint64_t_le2host(header->entry_lba), 
-			nearest_larger_int((uint64_t_le2host(header->raw_data->entry_size) * parts->num_ent) / b_size), 
+	rc = block_write_direct(dev_handle, uint64_t_le2host(gpt->raw_data->entry_lba), 
+			nearest_larger_int((uint64_t_le2host(gpt->raw_data->entry_size) * parts->num_ent) / b_size), 
 			parts->part_array);
 	if (rc != EOK)
@@ -254,7 +277,17 @@
 	
 	
-	gpt_write_gpt_header(header, dev_handle);
+	gpt_write_gpt_header(gpt, dev_handle);
 	
 	return 0;
+	
+}
+
+gpt_parts_t * gpt_add_partition(gpt_parts_t * parts, g_part_t * partition)
+{
+	
+}
+
+gpt_parts_t * gpt_remove_partition(gpt_parts_t * parts, int idx)
+{
 	
 }
@@ -263,5 +296,5 @@
 void gpt_free_gpt(gpt_t * gpt)
 {
-	free(gpt->header_lba);
+	free(gpt->raw_data);
 	free(gpt);
 }
@@ -286,27 +319,27 @@
 {
 	/* Beware: first 3 blocks are byteswapped! */
-	p->raw_data.part_type[3] = gpt_ptypes[type][0];
-	p->raw_data.part_type[2] = gpt_ptypes[type][1];
-	p->raw_data.part_type[1] = gpt_ptypes[type][2];
-	p->raw_data.part_type[0] = gpt_ptypes[type][3];
-	
-	p->raw_data.part_type[5] = gpt_ptypes[type][4];
-	p->raw_data.part_type[4] = gpt_ptypes[type][5];
-	
-	p->raw_data.part_type[7] = gpt_ptypes[type][6];
-	p->raw_data.part_type[6] = gpt_ptypes[type][7];
-	
-	p->raw_data.part_type[8] = gpt_ptypes[type][8];
-	p->raw_data.part_type[9] = gpt_ptypes[type][9];
-	p->raw_data.part_type[10] = gpt_ptypes[type][10];
-	p->raw_data.part_type[11] = gpt_ptypes[type][11];
-	p->raw_data.part_type[12] = gpt_ptypes[type][12];
-	p->raw_data.part_type[13] = gpt_ptypes[type][13];
-	p->raw_data.part_type[14] = gpt_ptypes[type][14];
-	p->raw_data.part_type[15] = gpt_ptypes[type][15];
+	p->raw_data.part_type[3] = gpt_ptypes[type].guid[0];
+	p->raw_data.part_type[2] = gpt_ptypes[type].guid[1];
+	p->raw_data.part_type[1] = gpt_ptypes[type].guid[2];
+	p->raw_data.part_type[0] = gpt_ptypes[type].guid[3];
+	
+	p->raw_data.part_type[5] = gpt_ptypes[type].guid[4];
+	p->raw_data.part_type[4] = gpt_ptypes[type].guid[5];
+	
+	p->raw_data.part_type[7] = gpt_ptypes[type].guid[6];
+	p->raw_data.part_type[6] = gpt_ptypes[type].guid[7];
+	
+	p->raw_data.part_type[8] = gpt_ptypes[type].guid[8];
+	p->raw_data.part_type[9] = gpt_ptypes[type].guid[9];
+	p->raw_data.part_type[10] = gpt_ptypes[type].guid[10];
+	p->raw_data.part_type[11] = gpt_ptypes[type].guid[11];
+	p->raw_data.part_type[12] = gpt_ptypes[type].guid[12];
+	p->raw_data.part_type[13] = gpt_ptypes[type].guid[13];
+	p->raw_data.part_type[14] = gpt_ptypes[type].guid[14];
+	p->raw_data.part_type[15] = gpt_ptypes[type].guid[15];
 }
 
 /** Copy partition name */
-void gpt_set_part_name(gpt_entry_t * p, char_t name[], size_t length)
+void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length)
 {
 	memcpy(p->part_name, name, length);
@@ -315,40 +348,39 @@
 // Internal functions follow //
 
-static int load_and_check_header(service_id_t handle, aoff64_t addr, gpt_t * header)
-{
-	rc = block_init(EXCHANGE_ATOMIC, handle, b_size);
-	if (rc != EOK)
-		return rc;
-	
-	rc = block_read_direct(handle, addr, GPT_HDR_BS, gpt->header_lba);
-	block_fini(handle);
-	if (rc != EOK)
-		return rc;
-	
-	
-	int i;
+static int load_and_check_header(service_id_t dev_handle, aoff64_t addr, size_t b_size, gpt_header_t * header)
+{
+	int rc;
+	
+	rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
+	if (rc != EOK)
+		return rc;
+	
+	rc = block_read_direct(dev_handle, addr, GPT_HDR_BS, header);
+	block_fini(dev_handle);
+	if (rc != EOK)
+		return rc;
+	
+	
+	unsigned int i;
 	/* Check the EFI signature */
 	for (i = 0; i < 8; ++i) {
-		if (gpt->header_lba.efi_signature[i] != efi_signature[i])
+		if (header->efi_signature[i] != efi_signature[i])
 			return EINVAL;
 	}
 	
 	/* Check the CRC32 of the header */
-	uint32_t crc = gpt->header_lba->header_crc32;
-	gpt->header_lba->header_crc32 = 0;
-	if (crc != compute_crc32(gpt->header_lba, gpt->header_lba->header_size))
+	uint32_t crc = header->header_crc32;
+	header->header_crc32 = 0;
+	if (crc != compute_crc32((uint8_t *) header, header->header_size))
 		return EBADCHECKSUM;
 	else
-		gpt->header_lba->header_crc32 = crc;
+		header->header_crc32 = crc;
 	
 	/* Check for zeroes in the rest of the block */
 	for (i = sizeof(gpt_header_t); i < b_size; ++i) {
-		if (((uint8_t *) gpt->header_lba)[i] != 0)
-			goto EINVAL;
-	}
-	
-	gpt->device = dev_handle;
-	//gpt->partitions = NULL;
-	
+		if (((uint8_t *) header)[i] != 0)
+			return EINVAL;
+	}
+		
 	return EOK;
 }
@@ -364,5 +396,5 @@
 	uint32_t size = num > GPT_BASE_PART_NUM ? num : GPT_BASE_PART_NUM;
 	res->part_array = malloc(size * sizeof(gpt_entry_t));
-	if (res.part_array == NULL) {
+	if (res->part_array == NULL) {
 		free(res);
 		errno = ENOMEM;
Index: uspace/lib/gpt/libgpt.h
===================================================================
--- uspace/lib/gpt/libgpt.h	(revision cbd640572786d277a31b5a1f8f88967e8962afd4)
+++ uspace/lib/gpt/libgpt.h	(revision 7570e80086a542f15630c4997dbb37e9720c123f)
@@ -36,4 +36,6 @@
 #define __GPT_H__
 
+#define NAME	"libgpt"
+
 #include <sys/types.h>
 
@@ -52,5 +54,7 @@
 };
 
-/** GPT header */
+/** GPT header
+ * - all in little endian.
+ */
 typedef struct {
 	uint8_t efi_signature[8];
@@ -77,6 +81,4 @@
 	service_id_t device;
 	/** Linked list of partitions (initially NULL) */
-	//g_part_t * partitions;	//shall we keep this? same problem as in libmbr
-	//NOTE: if we have partition list here, do we free() it or not? 
 } gpt_t;
 
@@ -109,5 +111,4 @@
 	/** Resizable partition array */
 	gpt_entry_t * part_array;
-	
 } gpt_parts_t;
 
@@ -115,7 +116,7 @@
 	const char * desc;
 	const char * guid;
-}
+};
 
-struct partition_type gpt_ptypes[] {
+struct partition_type gpt_ptypes[] = {
 	{ "Unused entry",					"00000000-0000-0000-0000-000000000000" },
 	{ "MBR partition scheme",			"024DEE41-33E7-11D3-9D69-0008C781F39F" },
@@ -184,10 +185,12 @@
 
 extern gpt_t * gpt_read_gpt_header(service_id_t dev_handle);
-extern int gpt_write_gpt_header(gpt_header_t header, service_id_t dev_handle);
+extern int gpt_write_gpt_header(gpt_t * header, service_id_t dev_handle);
 
 extern gpt_parts_t * gpt_read_partitions(gpt_t * gpt);
-extern int gpt_write_partitions(gpt_parts_t * parts, gpt_t * header);
-extern gpt_parts_t * gpt_add_partition(gpt_parts_t * parts, g_part_t partition);
-extern gpt_parts_t * gpt_remove_partition(gpt_parts_t * parts, int idx);
+extern int 			 gpt_write_partitions(gpt_parts_t * parts, gpt_t * header, service_id_t dev_handle);
+extern int			 gpt_add_partition(gpt_parts_t * parts, g_part_t * partition);
+extern void			 gpt_remove_partition(gpt_parts_t * parts, int idx);
+extern void 		 gpt_set_part_type(g_part_t * p, int type);
+extern void 		 gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length);
 
 extern void gpt_free_gpt(gpt_t * gpt);
