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

Side by Side Diff: installer/src/installer-lib/property.cpp

Issue 6202981292703744: Whole installer (Closed)
Patch Set: Created June 24, 2014, 7:27 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /** 1 /**
2 * \file property.cpp Implementation of Property class etc. 2 * \file property.cpp Implementation of Property class etc.
3 */ 3 */
4 4
5 #include "installer-lib.h"
5 #include "property.h" 6 #include "property.h"
6 #include "session.h" 7 #include "session.h"
7 #include "msiquery.h" 8 #include <msiquery.h>
8 #include <memory> 9 #include <memory>
9 10
10 //------------------------------------------------------------------------------ ----------- 11 //------------------------------------------------------------------------------ -----------
11 // Property 12 // Property
12 //------------------------------------------------------------------------------ ----------- 13 //------------------------------------------------------------------------------ -----------
13 Property::Property( Session & session, std::wstring name ) 14 Property::Property( Session & session, std::wstring name )
14 // VSE 2012 shows an IntelliSense error here. Ignore it. The compiler properly sees the 'friend' declaration. 15 // VSE 2012 shows an IntelliSense error here. Ignore it. The compiler properly sees the 'friend' declaration.
15 : handle( session.handle ), name( name ) 16 : handle( session.handle ), name( name )
16 {} 17 {}
17 18
18 /** 19 /**
19 * \par Implementation 20 * \par Implementation
20 * 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>. 21 * 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>.
21 */ 22 */
22 Property::operator std::wstring() const 23 Property::operator std::wstring() const
23 { 24 {
24 /* 25 /*
25 * The screwy logic below arises from how the API works. 26 * The first call gets the size, but also the actual value if it's short enough .
26 * MsiGetProperty insists on copying into your buffer, but you don't know how long that buffer needs to be in advance. 27 * A second call, if necessary, allocates a sufficiently-long buffer and then g ets the full value.
27 * The first call gets the size, but also the actual value if it's short enoug h. 28 * We use only a modest fixed-size buffer for the first step, because we handle arbitrary-length property values in a second step.
28 * A second call, if necessary, gets the actual value after allocat 29 */
29 */ 30 // This buffer allocates on the stack, so we don't want it too large; 64 chara cters is enough for most properties anyway.
30 // We only need a modest fixed-size buffer here, because we handle arbitrary-l ength property values in a second step. 31 WCHAR buffer1[ 64 ] = { L'\0' } ;
31 // It has 'auto' allocation, so we don't want it too large. 32 DWORD length = sizeof( buffer1 ) / sizeof( WCHAR ) ;
32 TCHAR buffer1[ 64 ] = { L'\0' } ; 33 UINT x = MsiGetPropertyW( handle, name.c_str(), buffer1, & length ) ;
33 DWORD length = sizeof( buffer1 ) / sizeof( TCHAR ) ; 34 switch ( x )
34 switch ( MsiGetProperty( handle, name.c_str(), buffer1, & length ) )
35 { 35 {
36 case ERROR_SUCCESS: 36 case ERROR_SUCCESS:
37 // This call might succeed, which means the return value was short enough to fit into the buffer. 37 // This call might succeed, which means the return value was short enough to fit into the buffer.
38 return std::wstring( buffer1, length ) ; 38 return std::wstring( buffer1, length ) ;
39 case ERROR_MORE_DATA: 39 case ERROR_MORE_DATA:
40 // Do nothing yet. 40 // Do nothing yet.
41 break ; 41 break ;
42 default: 42 default:
43 throw std::runtime_error( "Error getting property" ) ; 43 throw windows_api_error( "MsiGetPropertyW", x, "fixed buffer" ) ;
44 } 44 }
45 // Assert we received ERROR_MORE_DATA 45 // Assert we received ERROR_MORE_DATA
46 // unique_ptr handles deallocation transparently 46 // unique_ptr handles deallocation transparently
47 std::unique_ptr< TCHAR[] > buffer2( new TCHAR[ length ] ); 47 std::unique_ptr< WCHAR[] > buffer2( new WCHAR[ length ] ) ;
48 switch ( MsiGetProperty( handle, name.c_str(), buffer2.get(), & length ) ) 48 x = MsiGetPropertyW( handle, name.c_str(), buffer2.get(), & length ) ;
49 switch ( x )
49 { 50 {
50 case ERROR_SUCCESS: 51 case ERROR_SUCCESS:
51 return std::wstring( buffer2.get(), length ) ; 52 return std::wstring( buffer2.get(), length ) ;
52 default: 53 default:
53 throw std::runtime_error( "Error getting property" ) ; 54 throw windows_api_error( "MsiGetPropertyW", x, "allocated buffer" ) ;
54 } 55 }
55 } 56 }
56 57
57 /** 58 /**
58 * \par Implementation 59 * \par Implementation
59 * 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>. 60 * 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>.
60 */ 61 */
61 void Property::operator=( const std::wstring & value ) 62 void Property::operator=( const std::wstring & value )
62 { 63 {
63 if ( MsiSetProperty( handle, name.c_str(), value.c_str() ) != ERROR_SUCCESS ) 64 UINT x = MsiSetPropertyW( handle, name.c_str(), value.c_str() ) ;
65 if ( x != ERROR_SUCCESS )
64 { 66 {
65 throw std::runtime_error( "Error setting property" ) ; 67 throw windows_api_error( "MsiSetPropertyW", x ) ;
66 } 68 }
67 } 69 }
OLDNEW

Powered by Google App Engine
This is Rietveld