Index: trunk/src/VBox/Main/MachineImpl.cpp
===================================================================
--- trunk/src/VBox/Main/MachineImpl.cpp	(revision 13355)
+++ trunk/src/VBox/Main/MachineImpl.cpp	(revision 13356)
@@ -2724,10 +2724,10 @@
 }
 
-STDMETHODIMP Machine::GetGuestProperty (INPTR BSTR aKey, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags)
+STDMETHODIMP Machine::GetGuestProperty (INPTR BSTR aName, BSTR *aValue, ULONG64 *aTimestamp, BSTR *aFlags)
 {
 #if !defined (VBOX_WITH_GUEST_PROPS)
     return E_NOTIMPL;
 #else
-    if (!VALID_PTR (aKey))
+    if (!VALID_PTR (aName))
         return E_INVALIDARG;
     if (!VALID_PTR (aValue))
@@ -2752,9 +2752,11 @@
              (it != mHWData->mGuestProperties.end()) && !found; ++it)
         {
-            if (it->mName == aKey)
+            if (it->mName == aName)
             {
+                char szFlags[MAX_FLAGS_LEN + 1];
                 it->mValue.cloneTo(aValue);
                 *aTimestamp = it->mTimestamp;
-                it->mFlags.cloneTo(aFlags);
+                writeFlags(it->mFlags, szFlags);
+                Bstr(szFlags).cloneTo(aFlags);
                 found = true;
             }
@@ -2770,5 +2772,5 @@
         alock.unlock();
 
-        rc = directControl->AccessGuestProperty (aKey, NULL, NULL,
+        rc = directControl->AccessGuestProperty (aName, NULL, NULL,
                                                  false /* isSetter */,
                                                  aValue, aTimestamp, aFlags);
@@ -2778,16 +2780,16 @@
 }
 
-STDMETHODIMP Machine::GetGuestPropertyValue (INPTR BSTR aKey, BSTR *aValue)
+STDMETHODIMP Machine::GetGuestPropertyValue (INPTR BSTR aName, BSTR *aValue)
 {
     ULONG64 dummyTimestamp;
     BSTR dummyFlags;
-    return GetGuestProperty(aKey, aValue, &dummyTimestamp, &dummyFlags);
-}
-
-STDMETHODIMP Machine::GetGuestPropertyTimestamp (INPTR BSTR aKey, ULONG64 *aTimestamp)
+    return GetGuestProperty(aName, aValue, &dummyTimestamp, &dummyFlags);
+}
+
+STDMETHODIMP Machine::GetGuestPropertyTimestamp (INPTR BSTR aName, ULONG64 *aTimestamp)
 {
     BSTR dummyValue;
     BSTR dummyFlags;
-    return GetGuestProperty(aKey, &dummyValue, aTimestamp, &dummyFlags);
+    return GetGuestProperty(aName, &dummyValue, aTimestamp, &dummyFlags);
 }
 
@@ -2797,4 +2799,6 @@
     return E_NOTIMPL;
 #else
+    using namespace guestProp;
+
     if (!VALID_PTR (aName))
         return E_INVALIDARG;
@@ -2803,4 +2807,8 @@
     if ((aFlags != NULL) && !VALID_PTR (aFlags))
         return E_INVALIDARG;
+    uint32_t fFlags = NILFLAG;
+    if (RT_FAILURE (validateFlags (Utf8Str(aFlags).raw(), &fFlags)))
+        return setError (E_INVALIDARG, tr ("Invalid flag values: '%ls'"),
+                aFlags);
 
     AutoCaller autoCaller (this);
@@ -2812,6 +2820,5 @@
     CheckComRCReturnRC (rc);
 
-    using namespace guestProp;
-    rc = E_FAIL;
+    rc = S_OK;
 
     if (!mHWData->mPropertyServiceActive)
@@ -2819,21 +2826,32 @@
         bool found = false;
         HWData::GuestProperty property;
-        for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin();
-             (it != mHWData->mGuestProperties.end()) && !found; ++it)
-            if (it->mName == aName)
-            {
-                property = *it;
-                mHWData.backup();
-                /* The backup() operation invalidates our iterator, so get a
-                 * new one. */
-                for (it = mHWData->mGuestProperties.begin();
-                     it->mName != aName; ++it)
-                    ;
-                mHWData->mGuestProperties.erase(it);
-                found = true;
-            }
-        if (found)
-        {
-            if (NULL != aValue)
+        property.mFlags = NILFLAG;
+        if (fFlags & TRANSIENT)
+            rc = setError (E_INVALIDARG, tr ("Cannot set a transient property when the machine is not running"));
+        if (SUCCEEDED (rc))
+        {
+            for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin();
+                (it != mHWData->mGuestProperties.end()) && !found; ++it)
+                if (it->mName == aName)
+                {
+                    property = *it;
+                    if (it->mFlags & (GUESTWRITE | READONLY))
+                        rc = setError (E_ACCESSDENIED, tr ("The property '%ls' cannot be changed by the host"), aName);
+                    else
+                    {
+                        mHWData.backup();
+                        /* The backup() operation invalidates our iterator, so get a
+                        * new one. */
+                        for (it = mHWData->mGuestProperties.begin();
+                            it->mName != aName; ++it)
+                            ;
+                        mHWData->mGuestProperties.erase(it);
+                    }
+                    found = true;
+                }
+        }
+        if (found && SUCCEEDED (rc))
+        {
+            if (aValue != NULL)
             {
                 RTTIMESPEC time;
@@ -2841,9 +2859,9 @@
                 property.mTimestamp = RTTimeSpecGetNano(RTTimeNow(&time));
                 if (aFlags != NULL)
-                    property.mFlags = aFlags;
+                    property.mFlags = fFlags;
                 mHWData->mGuestProperties.push_back(property);
             }
         }
-        else if (aValue != NULL)
+        else if (SUCCEEDED (rc) && (aValue != NULL))
         {
             RTTIMESPEC time;
@@ -2852,8 +2870,7 @@
             property.mValue = aValue;
             property.mTimestamp = RTTimeSpecGetNano(RTTimeNow(&time));
-            property.mFlags = (aFlags != NULL ? Bstr(aFlags) : Bstr(""));
+            property.mFlags = fFlags;
             mHWData->mGuestProperties.push_back(property);
         }
-        rc = S_OK;
     }
     else
@@ -3034,8 +3051,10 @@
              it != propList.end(); ++it)
         {
+             char szFlags[MAX_FLAGS_LEN + 1];
              it->mName.cloneTo(&names[iProp]);
              it->mValue.cloneTo(&values[iProp]);
              timestamps[iProp] = it->mTimestamp;
-             it->mFlags.cloneTo(&flags[iProp]);
+             writeFlags(it->mFlags, szFlags);
+             Bstr(szFlags).cloneTo(&flags[iProp]);
              ++iProp;
         }
@@ -5020,6 +5039,9 @@
     }
 
+#ifdef VBOX_WITH_GUEST_PROPS
     /* Guest properties (optional) */
     {
+        using namespace guestProp;
+
         Key guestPropertiesNode = aNode.findKey ("GuestProperties");
         if (!guestPropertiesNode.isNull())
@@ -5029,4 +5051,6 @@
                  it != properties.end(); ++ it)
             {
+                uint32_t fFlags = NILFLAG;
+
                 /* property name (required) */
                 Bstr name = (*it).stringValue ("name");
@@ -5037,6 +5061,6 @@
                 /* property flags (optional, defaults to empty) */
                 Bstr flags = (*it).stringValue ("flags");
-
-                HWData::GuestProperty property = { name, value, timestamp, flags };
+                validateFlags (Utf8Str (flags).raw(), &fFlags);
+                HWData::GuestProperty property = { name, value, timestamp, fFlags };
                 mHWData->mGuestProperties.push_back(property);
             }
@@ -5044,4 +5068,5 @@
         mHWData->mPropertyServiceActive = false;
     }
+#endif /* VBOX_WITH_GUEST_PROPS defined */
 
     AssertComRC (rc);
@@ -6405,6 +6430,9 @@
     }
 
+#ifdef VBOX_WITH_GUEST_PROPS
     /* Guest properties */
     {
+        using namespace guestProp;
+
         Key guestPropertiesNode = aNode.createKey ("GuestProperties");
 
@@ -6416,11 +6444,14 @@
 
             Key propertyNode = guestPropertiesNode.appendKey ("GuestProperty");
+            char szFlags[MAX_FLAGS_LEN + 1];
 
             propertyNode.setValue <Bstr> ("name", property.mName);
             propertyNode.setValue <Bstr> ("value", property.mValue);
             propertyNode.setValue <ULONG64> ("timestamp", property.mTimestamp);
-            propertyNode.setValue <Bstr> ("flags", property.mFlags);
-        }
-    }
+            writeFlags(property.mFlags, szFlags);
+            propertyNode.setValue <Bstr> ("flags", Bstr(szFlags));
+        }
+    }
+#endif /* VBOX_WITH_GUEST_PROPS defined */
 
     AssertComRC (rc);
@@ -8976,4 +9007,6 @@
 
 #ifdef VBOX_WITH_GUEST_PROPS
+    using namespace guestProp;
+
     AutoCaller autoCaller (this);
     AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
@@ -8995,8 +9028,10 @@
          it != mHWData->mGuestProperties.end(); ++it)
     {
+        char szFlags[MAX_FLAGS_LEN + 1];
         it->mName.cloneTo(&names[i]);
         it->mValue.cloneTo(&values[i]);
         timestamps[i] = it->mTimestamp;
-        it->mFlags.cloneTo(&flags[i]);
+        writeFlags(it->mFlags, szFlags);
+        Bstr(szFlags).cloneTo(&flags[i]);
         ++i;
     }
@@ -9008,5 +9043,5 @@
     return S_OK;
 #else
-    return VERR_NOT_IMPLEMENTED;
+    return E_NOTIMPL;
 #endif
 }
@@ -9020,4 +9055,6 @@
 
 #ifdef VBOX_WITH_GUEST_PROPS
+    using namespace guestProp;
+
     AutoCaller autoCaller (this);
     AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
@@ -9052,5 +9089,7 @@
     for (unsigned i = 0; i < names.size(); ++i)
     {
-        HWData::GuestProperty property = { names[i], values[i], timestamps[i], flags[i] };
+        uint32_t fFlags = NILFLAG;
+        validateFlags (Utf8Str(flags[i]).raw(), &fFlags);
+        HWData::GuestProperty property = { names[i], values[i], timestamps[i], fFlags };
         mHWData->mGuestProperties.push_back(property);
     }
@@ -9062,5 +9101,5 @@
     return S_OK;
 #else
-    return VERR_NOT_IMPLEMENTED;
+    return E_NOTIMPL;
 #endif
 }
@@ -9072,8 +9111,14 @@
 
 #ifdef VBOX_WITH_GUEST_PROPS
+    using namespace guestProp;
+
     if (!VALID_PTR(aName))
+        return E_POINTER;
+    if ((aValue != NULL) && (!VALID_PTR(aValue) || !VALID_PTR(aFlags)))
+        return E_POINTER;  /* aValue can be NULL to indicate deletion */
+
+    uint32_t fFlags = NILFLAG;
+    if (RT_FAILURE (validateFlags (Utf8Str(aFlags).raw(), &fFlags)))
         return E_INVALIDARG;
-    if ((aValue != NULL) && (!VALID_PTR(aValue) || !VALID_PTR(aFlags)))
-        return E_INVALIDARG;  /* aValue can be NULL to indicate deletion */
 
     AutoCaller autoCaller (this);
@@ -9095,5 +9140,5 @@
     if (aValue != NULL)
     {
-        HWData::GuestProperty property = { aName, aValue, aTimestamp, aFlags };
+        HWData::GuestProperty property = { aName, aValue, aTimestamp, fFlags };
         mHWData->mGuestProperties.push_back(property);
     }
@@ -9105,5 +9150,5 @@
     return S_OK;
 #else
-    return VERR_NOT_IMPLEMENTED;
+    return E_NOTIMPL;
 #endif
 }
Index: trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- trunk/src/VBox/Main/include/MachineImpl.h	(revision 13355)
+++ trunk/src/VBox/Main/include/MachineImpl.h	(revision 13356)
@@ -240,5 +240,5 @@
             ULONG64 mTimestamp;
             /** Property flags */
-            Bstr mFlags;
+            ULONG mFlags;
         };
 
