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

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

Issue 22887001: Custom action library, initial version (Closed)
Patch Set: Created Oct. 28, 2013, 9:37 p.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
(Empty)
1 /**
2 * \file property.cpp Implementation of Property class etc.
3 */
4
5 #include "property.h"
6 #include "session.h"
7 #include "msiquery.h"
8 #include <memory>
9
10 //------------------------------------------------------------------------------ -----------
11 // Property
12 //------------------------------------------------------------------------------ -----------
13 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 : handle( session.handle ), name( name )
16 {}
17
18 /**
19 * \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 */
22 Property::operator std::wstring() const
23 {
24 /*
25 * The screwy logic below arises from how the API works.
26 * MsiGetProperty insists on copying into your buffer, but you don't know how long that buffer needs to be in advance.
27 * The first call gets the size, but also the actual value if it's short enoug h.
28 * A second call, if necessary, gets the actual value after allocat
29 */
Wladimir Palant 2013/10/29 08:49:26 The logic is actually common for any API that does
Eric 2013/10/29 14:00:58 I'll rewrite the comment. Reading it again, it doe
30 // We only need a modest fixed-size buffer here, because we handle arbitrary-l ength property values in a second step.
31 // It has 'auto' allocation, so we don't want it too large.
32 TCHAR buffer1[ 64 ] = { L'\0' } ;
33 DWORD length = sizeof( buffer1 ) / sizeof( TCHAR ) ;
Wladimir Palant 2013/10/29 08:49:26 sizeof(TCHAR) => sizeof(buffer1[0])?
Eric 2013/10/29 14:00:58 TCHAR is, as I recall, a wchar_t for Unicode compi
Wladimir Palant 2013/10/29 15:06:38 What I meant: you can replace sizeof(TCHAR) by siz
34 switch ( MsiGetProperty( handle, name.c_str(), buffer1, & length ) )
35 {
36 case ERROR_SUCCESS:
37 // This call might succeed, which means the return value was short enough to fit into the buffer.
38 return std::wstring( buffer1, length ) ;
39 case ERROR_MORE_DATA:
40 // Do nothing yet.
41 break ;
42 default:
43 throw std::runtime_error( "Error getting property" ) ;
44 }
45 // Assert we received ERROR_MORE_DATA
46 // unique_ptr handles deallocation transparently
47 std::unique_ptr< TCHAR[] > buffer2( new TCHAR[ length ] );
48 switch ( MsiGetProperty( handle, name.c_str(), buffer2.get(), & length ) )
49 {
50 case ERROR_SUCCESS:
51 return std::wstring( buffer2.get(), length ) ;
52 default:
53 throw std::runtime_error( "Error getting property" ) ;
54 }
Wladimir Palant 2013/10/29 08:49:26 Any reason why this isn't an if..else.. block? Als
Eric 2013/10/29 14:00:58 There are three other error codes defined for the
55 }
56
57 /**
58 * \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 */
61 void Property::operator=( const std::wstring & value )
62 {
63 if ( MsiSetProperty( handle, name.c_str(), value.c_str() ) != ERROR_SUCCESS )
64 {
65 throw std::runtime_error( "Error setting property" ) ;
Wladimir Palant 2013/10/29 08:49:26 This exception isn't very helpful, it should conta
Eric 2013/10/29 14:00:58 Admittedly, the exceptions here are stubs. I don't
Wladimir Palant 2013/10/29 15:06:38 Forgot to mention that: where are these exceptions
Eric 2014/03/28 13:56:38 The answer is a general one. Every time you use
66 }
67 }
OLDNEW

Powered by Google App Engine
This is Rietveld