Index: uspace/lib/gpt/libgpt.c
===================================================================
--- uspace/lib/gpt/libgpt.c	(revision 30440ed9f60f88be5148ec4174eb978d617e65d2)
+++ uspace/lib/gpt/libgpt.c	(revision d6170504a73b910b4963928493001f52b1c18826)
@@ -56,8 +56,9 @@
 static int reduce_part_array(gpt_partitions_t * p);
 static long long nearest_larger_int(double a);
+static int gpt_memcmp(const void * a, const void * b, size_t len);
 
 /** Read GPT from specific device
  * @param	dev_handle	device to read GPT from
- * 
+ *
  * @return				GPT record on success, NULL on error
  */
@@ -66,5 +67,5 @@
 	int rc;
 	size_t b_size;
-	
+
 	rc = block_get_bsize(dev_handle, &b_size);
 	if (rc != EOK) {
@@ -72,5 +73,5 @@
 		return NULL;
 	}
-	
+
 	gpt_t * gpt = malloc(sizeof(gpt_t));
 	if (gpt == NULL) {
@@ -78,13 +79,13 @@
 		return NULL;
 	}
-	
+
 	gpt->raw_data = malloc(b_size);// We might need only sizeof(gpt_header_t),
-	if (gpt == NULL) {				// but we should follow specs and have 
+	if (gpt == NULL) {				// but we should follow specs and have
 		free(gpt);					// zeroes through all the rest of the block
 		errno = ENOMEM;
 		return NULL;
 	}
-	
-	
+
+
 	rc = load_and_check_header(dev_handle, GPT_HDR_BA, b_size, gpt->raw_data);
 	if (rc == EBADCHECKSUM || rc == EINVAL) {
@@ -95,5 +96,5 @@
 			goto fail;
 		}
-		
+
 		rc = load_and_check_header(dev_handle, n_blocks - 1, b_size, gpt->raw_data);
 		if (rc == EBADCHECKSUM || rc == EINVAL) {
@@ -102,7 +103,7 @@
 		}
 	}
-	
+
 	gpt->device = dev_handle;
-	
+
 	return gpt;
 
@@ -115,7 +116,7 @@
  * @param header		GPT header to be written
  * @param dev_handle	device handle to write the data to
- * 
+ *
  * @return				0 on success, libblock error code otherwise
- * 
+ *
  * Note: Firstly write partitions (if changed), then gpt header.
  */
@@ -124,17 +125,17 @@
 	int rc;
 	size_t b_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);
 	if (rc != EOK)
 		return rc;
-	
+
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
 	if (rc != EOK)
 		return rc;
-	
+
 	/* Write to main GPT header location */
 	rc = block_write_direct(dev_handle, GPT_HDR_BA, GPT_HDR_BS, gpt->raw_data);
@@ -142,10 +143,10 @@
 		block_fini(dev_handle);
 		return rc;
-	
+
 	aoff64_t n_blocks;
 	rc = block_get_nblocks(dev_handle, &n_blocks);
 	if (rc != EOK)
 		return rc;
-	
+
 	/* Write to backup GPT header location */
 	//FIXME: those idiots thought it would be cool to have these fields in reverse order...
@@ -154,5 +155,5 @@
 	if (rc != EOK)
 		return rc;
-		
+
 	return 0;
 }
@@ -160,5 +161,5 @@
 /** Parse partitions from GPT
  * @param gpt	GPT to be parsed
- * 
+ *
  * @return 		partition linked list pointer or NULL on error
  * 				error code is stored in errno
@@ -172,5 +173,5 @@
 	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(fill);
 	if (res == NULL) {
@@ -178,5 +179,5 @@
 		return NULL;
 	}
-	
+
 	/* We can limit comm_size like this:
 	 *  - we don't need more bytes
@@ -188,5 +189,5 @@
 		return NULL;
 	}
-	
+
 	size_t block_size;
 	rc = block_get_bsize(gpt->device, &block_size);
@@ -196,9 +197,9 @@
 		return NULL;
 	}
-	
+
 	//size_t bufpos = 0;
 	//size_t buflen = 0;
 	aoff64_t pos = ent_lba * block_size;
-	
+
 	/* Now we read just sizeof(gpt_entry_t) bytes for each entry from the device.
 	 * Hopefully, this does not bypass cache (no mention in libblock.c),
@@ -212,5 +213,5 @@
 		//rc = block_seqread(gpt->device, &bufpos, &buflen, &pos, res->part_array[i], sizeof(gpt_entry_t));
 		pos += ent_size;
-		
+
 		if (rc != EOK) {
 			gpt_free_partitions(res);
@@ -219,5 +220,5 @@
 		}
 	}
-	
+
 	/* FIXME: so far my boasting about variable partition entry size
 	 * will not work. The CRC32 checksums will be different.
@@ -226,5 +227,5 @@
 	 */
 	uint32_t crc = compute_crc32((uint8_t *) res->part_array, res->fill * sizeof(gpt_entry_t));
-	
+
 	if(uint32_t_le2host(gpt->raw_data->pe_array_crc32) != crc)
 	{
@@ -233,5 +234,5 @@
 		return NULL;
 	}
-	
+
 	return res;
 }
@@ -241,5 +242,5 @@
  * @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
  */
@@ -248,28 +249,28 @@
 	int rc;
 	size_t b_size;
-	
+
 	gpt->raw_data->pe_array_crc32 = compute_crc32((uint8_t *) parts->part_array, parts->fill * gpt->raw_data->entry_size);
-	
+
 	rc = block_get_bsize(dev_handle, &b_size);
 	if (rc != EOK)
 		return rc;
-	
+
 	rc = block_init(EXCHANGE_ATOMIC, dev_handle, b_size);
 	if (rc != EOK)
 		return rc;
-	
+
 	/* Write to main GPT partition array location */
-	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->fill) / 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->fill) / b_size),
 			parts->part_array);
 	if (rc != EOK)
 		block_fini(dev_handle);
 		return rc;
-	
+
 	aoff64_t n_blocks;
 	rc = block_get_nblocks(dev_handle, &n_blocks);
 	if (rc != EOK)
 		return rc;
-	
+
 	/* Write to backup GPT partition array location */
 	//rc = block_write_direct(dev_handle, n_blocks - 1, GPT_HDR_BS, header->raw_data);
@@ -277,17 +278,17 @@
 	if (rc != EOK)
 		return rc;
-	
-	
+
+
 	return gpt_write_gpt_header(gpt, dev_handle);
 }
 
 /** Alloc new partition
- * 
+ *
  * @param parts		partition table to carry new partition
- * 
+ *
  * @return			returns pointer to the new partition or NULL on ENOMEM
- * 
+ *
  * Note: use either gpt_alloc_partition or gpt_add_partition. The first
- * returns a pointer to write your data to, the second copies the data 
+ * returns a pointer to write your data to, the second copies the data
  * (and does not free the memory).
  */
@@ -298,17 +299,17 @@
 			return NULL;
 	}
-	
+
 	return parts->part_array + parts->fill++;
 }
 
 /** Copy partition into partition array
- * 
+ *
  * @param parts			target partition array
  * @param partition		source partition to copy
- * 
+ *
  * @return 				-1 on error, 0 otherwise
- * 
+ *
  * Note: use either gpt_alloc_partition or gpt_add_partition. The first
- * returns a pointer to write your data to, the second copies the data 
+ * returns a pointer to write your data to, the second copies the data
  * (and does not free the memory).
  */
@@ -317,16 +318,16 @@
 	if (parts->fill == parts->arr_size) {
 		if (extend_part_array(parts) == -1)
-			return -1;
+			return ENOMEM;
 	}
 	extend_part_array(parts);
-	return parts;
+	return EOK;;
 }
 
 /** Remove partition from array
- * 
+ *
  * @param idx		index of the partition to remove
- * 
+ *
  * @return			-1 on error, 0 otherwise
- * 
+ *
  * Note: even if it fails, the partition still gets removed. Only
  * reducing the array failed.
@@ -335,13 +336,13 @@
 {
 	if (idx != parts->fill - 1) {
-		memcpy(parts->part_array + idx, parts->part_array + fill - 1, sizeof(gpt_entry_t));
+		memcpy(parts->part_array + idx, parts->part_array + parts->fill - 1, sizeof(gpt_entry_t));
 		parts->fill -= 1;
 	}
-	
+
 	if (parts->fill < (parts->arr_size / 2) - GPT_IGNORE_FILL_NUM) {
 		if (reduce_part_array(parts) == -1)
 			return -1;
 	}
-	
+
 	return 0;
 }
@@ -355,5 +356,5 @@
 
 /** Free partition list
- * 
+ *
  * @param parts		partition list to be freed
  */
@@ -371,5 +372,5 @@
 	size_t i;
 	for (i = 0; gpt_ptypes[i].guid != NULL; i++) {
-		if (memcmp(p->raw_data.part_type, gpt_ptypes[i].guid, 16) == 0) {
+		if (gpt_memcmp(p->part_type, gpt_ptypes[i].guid, 16) == 0) {
 			break;
 		}
@@ -381,42 +382,66 @@
  * @param p			partition to be set
  * @param type		partition type to set
- * 					- see gpt_ptypes to choose from
- * 
- */
-void gpt_set_part_type(gpt_part_t * p, int type)
+ * 					- see our fine selection at gpt_ptypes to choose from
+ */
+void gpt_set_part_type(gpt_part_t * p, size_t type)
 {
 	/* Beware: first 3 blocks are byteswapped! */
-	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];
-}
-
-char * gpt_get_part_name(gpt_entry_t * p)
-{
-	return p->raw_data.part_name;
+	p->part_type[3] = gpt_ptypes[type].guid[0];
+	p->part_type[2] = gpt_ptypes[type].guid[1];
+	p->part_type[1] = gpt_ptypes[type].guid[2];
+	p->part_type[0] = gpt_ptypes[type].guid[3];
+
+	p->part_type[5] = gpt_ptypes[type].guid[4];
+	p->part_type[4] = gpt_ptypes[type].guid[5];
+
+	p->part_type[7] = gpt_ptypes[type].guid[6];
+	p->part_type[6] = gpt_ptypes[type].guid[7];
+
+	p->part_type[8] = gpt_ptypes[type].guid[8];
+	p->part_type[9] = gpt_ptypes[type].guid[9];
+	p->part_type[10] = gpt_ptypes[type].guid[10];
+	p->part_type[11] = gpt_ptypes[type].guid[11];
+	p->part_type[12] = gpt_ptypes[type].guid[12];
+	p->part_type[13] = gpt_ptypes[type].guid[13];
+	p->part_type[14] = gpt_ptypes[type].guid[14];
+	p->part_type[15] = gpt_ptypes[type].guid[15];
+}
+
+/** Get partition starting LBA */
+uint64_t gpt_get_start_lba(gpt_part_t * p)
+{
+	return uint64_t_le2host(p->start_lba);
+}
+
+/** Set partition starting LBA */
+void gpt_set_start_lba(gpt_part_t * p, uint64_t start)
+{
+	p->start_lba = host2uint64_t_le(start);
+}
+
+/** Get partition ending LBA */
+uint64_t gpt_get_end_lba(gpt_part_t * p)
+{
+	return uint64_t_le2host(p->end_lba);
+}
+
+/** Set partition ending LBA */
+void gpt_set_end_lba(gpt_part_t * p, uint64_t end)
+{
+	p->end_lba = host2uint64_t_le(end);
+}
+
+
+unsigned char * gpt_get_part_name(gpt_part_t * p)
+{
+	return p->part_name;
 }
 
 /** Copy partition name */
-void gpt_set_part_name(gpt_entry_t * p, char * name[], size_t length)
+void gpt_set_part_name(gpt_part_t * p, char * name[], size_t length)
 {
 	if (length >= 72)
 		length = 71;
-	
+
 	memcpy(p->part_name, name, length);
 	p->part_name[length] = '\0';
@@ -424,13 +449,13 @@
 
 /** Get partition attribute */
-extern bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag)
-{
-	return (p->raw_data.attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
+bool gpt_get_flag(gpt_part_t * p, GPT_ATTR flag)
+{
+	return (p->attributes & (((uint64_t) 1) << flag)) ? 1 : 0;
 }
 
 /** Set partition attribute */
-extern void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value)
-{
-	uint64_t attr = p->raw_data.attributes;
+void gpt_set_flag(gpt_part_t * p, GPT_ATTR flag, bool value)
+{
+	uint64_t attr = p->attributes;
 
 	if (value)
@@ -439,5 +464,5 @@
 		attr = attr ^ (attr & (((uint64_t) 1) << flag));
 
-	p->raw_data.attributes = attr;
+	p->attributes = attr;
 }
 
@@ -447,15 +472,15 @@
 {
 	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 */
@@ -464,5 +489,5 @@
 			return EINVAL;
 	}
-	
+
 	/* Check the CRC32 of the header */
 	uint32_t crc = header->header_crc32;
@@ -472,5 +497,5 @@
 	else
 		header->header_crc32 = crc;
-	
+
 	/* Check for zeroes in the rest of the block */
 	for (i = sizeof(gpt_header_t); i < b_size; ++i) {
@@ -478,5 +503,5 @@
 			return EINVAL;
 	}
-		
+
 	return EOK;
 }
@@ -489,5 +514,5 @@
 		return NULL;
 	}
-	
+
 	uint32_t size = num > GPT_BASE_PART_NUM ? num : GPT_BASE_PART_NUM;
 	res->part_array = malloc(size * sizeof(gpt_entry_t));
@@ -497,8 +522,8 @@
 		return NULL;
 	}
-	
+
 	res->fill = num;
 	res->arr_size = size;
-	
+
 	return res;
 }
@@ -512,10 +537,10 @@
 		return -1;
 	}
-	
+
 	memcpy(tmp, p->part_array, p->fill);
 	free(p->part_array);
 	p->part_array = tmp;
 	p->arr_size = nsize;
-	
+
 	return 0;
 }
@@ -530,5 +555,5 @@
 			return -1;
 		}
-		
+
 		memcpy(tmp, p->part_array, p->fill < nsize ? p->fill  : nsize);
 		free(p->part_array);
@@ -536,5 +561,5 @@
 		p->arr_size = nsize;
 	}
-	
+
 	return 0;
 }
@@ -546,9 +571,25 @@
 		return (long long) a;
 	}
-	
+
 	return ((long long) a) + 1;
 }
 
-
-
-
+static int gpt_memcmp(const void * a, const void * b, size_t len)
+{
+	size_t i;
+	int diff;
+	const unsigned char * x = a;
+	const unsigned char * y = b;
+
+	for (i = 0; i < len; i++) {
+		diff = (int)*(x++) - (int)*(y++);
+		if (diff != 0) {
+			return diff;
+		}
+	}
+	return 0;
+}
+
+
+
+
