Andrew Nguyen : propsys: Implement PSPropertyKeyFromString.

Alexandre Julliard julliard at winehq.org
Mon Jul 26 13:22:33 CDT 2010


Module: wine
Branch: master
Commit: 9d85d46a1a42fa8249d35cbe6f97ca2d0ce35bd2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9d85d46a1a42fa8249d35cbe6f97ca2d0ce35bd2

Author: Andrew Nguyen <anguyen at codeweavers.com>
Date:   Sun Jul 25 21:58:07 2010 -0500

propsys: Implement PSPropertyKeyFromString.

---

 dlls/propsys/propsys.spec   |    2 +-
 dlls/propsys/propsys_main.c |  142 +++++++++++++++++++++++++++++++++++++++++++
 include/propsys.idl         |    1 +
 3 files changed, 144 insertions(+), 1 deletions(-)

diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec
index cd41d90..10a1cba 100644
--- a/dlls/propsys/propsys.spec
+++ b/dlls/propsys/propsys.spec
@@ -87,7 +87,7 @@
 @ stub PSGetPropertySystem
 @ stub PSGetPropertyValue
 @ stub PSLookupPropertyHandlerCLSID
-@ stub PSPropertyKeyFromString
+@ stdcall PSPropertyKeyFromString(wstr ptr)
 @ stub PSRefreshPropertySchema
 @ stdcall PSRegisterPropertySchema(wstr)
 @ stub PSSetPropertyValue
diff --git a/dlls/propsys/propsys_main.c b/dlls/propsys/propsys_main.c
index cd180fe..35efda8 100644
--- a/dlls/propsys/propsys_main.c
+++ b/dlls/propsys/propsys_main.c
@@ -1,6 +1,7 @@
 /*
  * propsys main
  *
+ * Copyright 1997, 2002 Alexandre Julliard
  * Copyright 2008 James Hawkins
  *
  * This library is free software; you can redistribute it and/or
@@ -130,3 +131,144 @@ HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch
         return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
     }
 }
+
+static const BYTE hex2bin[] =
+{
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x00 */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x10 */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x20 */
+    0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,        /* 0x30 */
+    0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,  /* 0x40 */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x50 */
+    0,10,11,12,13,14,15                     /* 0x60 */
+};
+
+static BOOL validate_indices(LPCWSTR s, int min, int max)
+{
+    int i;
+
+    for (i = min; i <= max; i++)
+    {
+        if (!s[i])
+            return FALSE;
+
+        if (i == 0)
+        {
+            if (s[i] != '{')
+                return FALSE;
+        }
+        else if (i == 9 || i == 14 || i == 19 || i == 24)
+        {
+            if (s[i] != '-')
+                return FALSE;
+        }
+        else if (i == 37)
+        {
+            if (s[i] != '}')
+                return FALSE;
+        }
+        else
+        {
+            if (s[i] > 'f' || (!hex2bin[s[i]] && s[i] != '0'))
+                return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+/* Adapted from CLSIDFromString helper in dlls/ole32/compobj.c and
+ * UuidFromString in dlls/rpcrt4/rpcrt4_main.c. */
+static BOOL string_to_guid(LPCWSTR s, LPGUID id)
+{
+    /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
+
+    if (!validate_indices(s, 0, 8)) return FALSE;
+    id->Data1 = (hex2bin[s[1]] << 28 | hex2bin[s[2]] << 24 | hex2bin[s[3]] << 20 | hex2bin[s[4]] << 16 |
+                 hex2bin[s[5]] << 12 | hex2bin[s[6]] << 8  | hex2bin[s[7]] << 4  | hex2bin[s[8]]);
+    if (!validate_indices(s, 9, 14)) return FALSE;
+    id->Data2 = hex2bin[s[10]] << 12 | hex2bin[s[11]] << 8 | hex2bin[s[12]] << 4 | hex2bin[s[13]];
+    if (!validate_indices(s, 15, 19)) return FALSE;
+    id->Data3 = hex2bin[s[15]] << 12 | hex2bin[s[16]] << 8 | hex2bin[s[17]] << 4 | hex2bin[s[18]];
+
+    /* these are just sequential bytes */
+
+    if (!validate_indices(s, 20, 21)) return FALSE;
+    id->Data4[0] = hex2bin[s[20]] << 4 | hex2bin[s[21]];
+    if (!validate_indices(s, 22, 24)) return FALSE;
+    id->Data4[1] = hex2bin[s[22]] << 4 | hex2bin[s[23]];
+
+    if (!validate_indices(s, 25, 26)) return FALSE;
+    id->Data4[2] = hex2bin[s[25]] << 4 | hex2bin[s[26]];
+    if (!validate_indices(s, 27, 28)) return FALSE;
+    id->Data4[3] = hex2bin[s[27]] << 4 | hex2bin[s[28]];
+    if (!validate_indices(s, 29, 30)) return FALSE;
+    id->Data4[4] = hex2bin[s[29]] << 4 | hex2bin[s[30]];
+    if (!validate_indices(s, 31, 32)) return FALSE;
+    id->Data4[5] = hex2bin[s[31]] << 4 | hex2bin[s[32]];
+    if (!validate_indices(s, 33, 34)) return FALSE;
+    id->Data4[6] = hex2bin[s[33]] << 4 | hex2bin[s[34]];
+    if (!validate_indices(s, 35, 37)) return FALSE;
+    id->Data4[7] = hex2bin[s[35]] << 4 | hex2bin[s[36]];
+
+    return TRUE;
+}
+
+HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey)
+{
+    int has_minus = 0;
+
+    TRACE("(%s, %p)\n", debugstr_w(pszString), pkey);
+
+    if (!pszString || !pkey)
+        return E_POINTER;
+
+    memset(pkey, 0, sizeof(PROPERTYKEY));
+
+    if (!string_to_guid(pszString, &pkey->fmtid))
+        return E_INVALIDARG;
+
+    pszString += GUIDSTRING_MAX - 1;
+
+    if (!*pszString)
+        return E_INVALIDARG;
+
+    /* Only the space seems to be recognized as whitespace. */
+    while (*pszString == ' ')
+        pszString++;
+
+    if (!*pszString)
+        return E_INVALIDARG;
+
+    /* Only two minus signs are recognized. The first is ignored, and the
+     * second is interpreted. */
+    if (*pszString == '-')
+        pszString++;
+
+    /* Skip any intermediate spaces after the first minus sign. */
+    while (*pszString == ' ')
+        pszString++;
+
+    if (*pszString == '-')
+    {
+        has_minus = 1;
+        pszString++;
+    }
+
+    /* Skip any remaining spaces after minus sign. */
+    while (*pszString == ' ')
+        pszString++;
+
+    /* Overflow is not checked. */
+    while (isdigitW(*pszString))
+    {
+        pkey->pid *= 10;
+        pkey->pid += (*pszString - '0');
+        pszString++;
+    }
+
+    if (has_minus)
+        pkey->pid = ~pkey->pid + 1;
+
+    return S_OK;
+}
diff --git a/include/propsys.idl b/include/propsys.idl
index c098041..da401c5 100644
--- a/include/propsys.idl
+++ b/include/propsys.idl
@@ -800,6 +800,7 @@ cpp_quote("#define GUIDSTRING_MAX 39")
 cpp_quote("#define PKEYSTR_MAX (GUIDSTRING_MAX + 1 + PKEY_PIDSTR_MAX)")
 
 cpp_quote("HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY,LPWSTR,UINT);")
+cpp_quote("HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR,PROPERTYKEY*);")
 
 /* TODO: Add remainder of the C api here */
 




More information about the wine-cvs mailing list