aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys/include/guidutils.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/unisys/include/guidutils.h')
-rw-r--r--drivers/staging/unisys/include/guidutils.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/drivers/staging/unisys/include/guidutils.h b/drivers/staging/unisys/include/guidutils.h
new file mode 100644
index 000000000000..75caf929cd6d
--- /dev/null
+++ b/drivers/staging/unisys/include/guidutils.h
@@ -0,0 +1,203 @@
+/* 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