blob: 75caf929cd6d412a11e8e156a3d279813046ccbb [file] [log] [blame]
/* Copyright © 2010 - 2013 UNISYS CORPORATION
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*/
/* guidutils.h
*
* These are GUID manipulation inlines that can be used from either
* kernel-mode or user-mode.
*
*/
#ifndef __GUIDUTILS_H__
#define __GUIDUTILS_H__
#ifdef __KERNEL__
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ctype.h>
#define GUID_STRTOUL kstrtoul
#else
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define GUID_STRTOUL strtoul
#endif
static inline char *
GUID_format1(const GUID *guid, char *s)
{
sprintf(s, "{%-8.8lx-%-4.4x-%-4.4x-%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x}",
(ulong) guid->data1,
guid->data2,
guid->data3,
guid->data4[0],
guid->data4[1],
guid->data4[2],
guid->data4[3],
guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
return s;
}
/** Format a GUID in Microsoft's 'what in the world were they thinking'
* format.
*/
static inline char *
GUID_format2(const GUID *guid, char *s)
{
sprintf(s, "{%-8.8lx-%-4.4x-%-4.4x-%-2.2x%-2.2x-%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x%-2.2x}",
(ulong) guid->data1,
guid->data2,
guid->data3,
guid->data4[0],
guid->data4[1],
guid->data4[2],
guid->data4[3],
guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
return s;
}
/**
* Like GUID_format2 but without the curly braces and the
* hex digits in upper case
*/
static inline char *
GUID_format3(const GUID *guid, char *s)
{
sprintf(s, "%-8.8lX-%-4.4X-%-4.4X-%-2.2X%-2.2X-%-2.2X%-2.2X%-2.2X%-2.2X%-2.2X%-2.2X",
(ulong) guid->data1,
guid->data2,
guid->data3,
guid->data4[0],
guid->data4[1],
guid->data4[2],
guid->data4[3],
guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
return s;
}
/** Parse a guid string in any of these forms:
* {11111111-2222-3333-4455-66778899aabb}
* {11111111-2222-3333-445566778899aabb}
* 11111111-2222-3333-4455-66778899aabb
* 11111111-2222-3333-445566778899aabb
*/
static inline GUID
GUID_scan(U8 *p)
{
GUID guid = GUID0;
U8 x[33];
int count = 0;
int c, i = 0;
U8 cdata1[9];
U8 cdata2[5];
U8 cdata3[5];
U8 cdata4[3];
int dashcount = 0;
int brace = 0;
unsigned long uldata;
if (!p)
return guid;
if (*p == '{') {
p++;
brace = 1;
}
while (count < 32) {
if (*p == '}')
return guid;
if (*p == '\0')
return guid;
c = toupper(*p);
p++;
if (c == '-') {
switch (dashcount) {
case 0:
if (i != 8)
return guid;
break;
case 1:
if (i != 4)
return guid;
break;
case 2:
if (i != 4)
return guid;
break;
case 3:
if (i != 4)
return guid;
break;
default:
return guid;
}
dashcount++;
i = 0;
continue;
}
if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
i++;
else
return guid;
x[count++] = c;
}
x[count] = '\0';
if (brace) {
if (*p == '}')
p++;
else
return guid;
}
if (dashcount == 3 || dashcount == 4)
;
else
return guid;
memset(cdata1, 0, sizeof(cdata1));
memset(cdata2, 0, sizeof(cdata2));
memset(cdata3, 0, sizeof(cdata3));
memset(cdata4, 0, sizeof(cdata4));
memcpy(cdata1, x + 0, 8);
memcpy(cdata2, x + 8, 4);
memcpy(cdata3, x + 12, 4);
if (GUID_STRTOUL((char *) cdata1, 16, &uldata) == 0)
guid.data1 = (U32)uldata;
if (GUID_STRTOUL((char *) cdata2, 16, &uldata) == 0)
guid.data2 = (U16)uldata;
if (GUID_STRTOUL((char *) cdata3, 16, &uldata) == 0)
guid.data3 = (U16)uldata;
for (i = 0; i < 8; i++) {
memcpy(cdata4, x + 16 + (i * 2), 2);
if (GUID_STRTOUL((char *) cdata4, 16, &uldata) == 0)
guid.data4[i] = (U8) uldata;
}
return guid;
}
static inline char *
GUID_sanitize(char *inputGuidStr, char *outputGuidStr)
{
GUID g;
GUID guid0 = GUID0;
*outputGuidStr = '\0';
g = GUID_scan((U8 *) inputGuidStr);
if (memcmp(&g, &guid0, sizeof(GUID)) == 0)
return outputGuidStr; /* bad GUID format */
return GUID_format1(&g, outputGuidStr);
}
#endif