Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: installer/src/installer-lib/property.cpp

Issue 6202981292703744: Whole installer (Closed)
Patch Set: Created June 24, 2014, 7:27 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: installer/src/installer-lib/property.cpp
===================================================================
--- a/installer/src/installer-lib/property.cpp
+++ b/installer/src/installer-lib/property.cpp
@@ -1,10 +1,11 @@
/**
- * \file property.cpp Implementation of Property class etc.
- */
+* \file property.cpp Implementation of Property class etc.
+*/
+#include "installer-lib.h"
#include "property.h"
#include "session.h"
-#include "msiquery.h"
+#include <msiquery.h>
#include <memory>
//-----------------------------------------------------------------------------------------
@@ -16,22 +17,21 @@
{}
/**
- * \par Implementation
- * The center of the implementation is the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370134%28v=vs.85%29.aspx">MsiGetProperty function</a>.
- */
+* \par Implementation
+* The center of the implementation is the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370134%28v=vs.85%29.aspx">MsiGetProperty function</a>.
+*/
Property::operator std::wstring() const
{
/*
- * The screwy logic below arises from how the API works.
- * MsiGetProperty insists on copying into your buffer, but you don't know how long that buffer needs to be in advance.
- * The first call gets the size, but also the actual value if it's short enough.
- * A second call, if necessary, gets the actual value after allocat
- */
- // We only need a modest fixed-size buffer here, because we handle arbitrary-length property values in a second step.
- // It has 'auto' allocation, so we don't want it too large.
- TCHAR buffer1[ 64 ] = { L'\0' } ;
- DWORD length = sizeof( buffer1 ) / sizeof( TCHAR ) ;
- switch ( MsiGetProperty( handle, name.c_str(), buffer1, & length ) )
+ * The first call gets the size, but also the actual value if it's short enough.
+ * A second call, if necessary, allocates a sufficiently-long buffer and then gets the full value.
+ * We use only a modest fixed-size buffer for the first step, because we handle arbitrary-length property values in a second step.
+ */
+ // This buffer allocates on the stack, so we don't want it too large; 64 characters is enough for most properties anyway.
+ WCHAR buffer1[ 64 ] = { L'\0' } ;
+ DWORD length = sizeof( buffer1 ) / sizeof( WCHAR ) ;
+ UINT x = MsiGetPropertyW( handle, name.c_str(), buffer1, & length ) ;
+ switch ( x )
{
case ERROR_SUCCESS:
// This call might succeed, which means the return value was short enough to fit into the buffer.
@@ -40,28 +40,30 @@
// Do nothing yet.
break ;
default:
- throw std::runtime_error( "Error getting property" ) ;
+ throw windows_api_error( "MsiGetPropertyW", x, "fixed buffer" ) ;
}
// Assert we received ERROR_MORE_DATA
// unique_ptr handles deallocation transparently
- std::unique_ptr< TCHAR[] > buffer2( new TCHAR[ length ] );
- switch ( MsiGetProperty( handle, name.c_str(), buffer2.get(), & length ) )
+ std::unique_ptr< WCHAR[] > buffer2( new WCHAR[ length ] ) ;
+ x = MsiGetPropertyW( handle, name.c_str(), buffer2.get(), & length ) ;
+ switch ( x )
{
case ERROR_SUCCESS:
return std::wstring( buffer2.get(), length ) ;
default:
- throw std::runtime_error( "Error getting property" ) ;
+ throw windows_api_error( "MsiGetPropertyW", x, "allocated buffer" ) ;
}
}
/**
- * \par Implementation
- * The center of the implementation is the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370391%28v=vs.85%29.aspx">MsiSetProperty function</a>.
- */
+* \par Implementation
+* The center of the implementation is the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370391%28v=vs.85%29.aspx">MsiSetProperty function</a>.
+*/
void Property::operator=( const std::wstring & value )
{
- if ( MsiSetProperty( handle, name.c_str(), value.c_str() ) != ERROR_SUCCESS )
+ UINT x = MsiSetPropertyW( handle, name.c_str(), value.c_str() ) ;
+ if ( x != ERROR_SUCCESS )
{
- throw std::runtime_error( "Error setting property" ) ;
+ throw windows_api_error( "MsiSetPropertyW", x ) ;
}
}

Powered by Google App Engine
This is Rietveld