Left: | ||
Right: |
OLD | NEW |
---|---|
1 /** | 1 /** |
2 * \file record.cpp Implementation of Record class. | 2 * \file record.cpp Implementation of Record class. |
3 */ | 3 */ |
4 | 4 |
5 #include "installer-lib.h" | |
5 #include "record.h" | 6 #include "record.h" |
6 #include "msiquery.h" | 7 #include "msiquery.h" |
7 | 8 |
8 //------------------------------------------------------------------------------ ----------- | 9 //------------------------------------------------------------------------------ ----------- |
9 // Record | 10 // Record |
10 //------------------------------------------------------------------------------ ----------- | 11 //------------------------------------------------------------------------------ ----------- |
11 Record::Record( unsigned int n_fields ) | 12 Record::Record( unsigned int n_fields ) |
12 { | 13 { |
13 _handle = MsiCreateRecord( n_fields ) ; | 14 _handle = MsiCreateRecord( n_fields ) ; |
14 if ( ! _handle ) | 15 if ( ! _handle ) |
15 { | 16 { |
16 throw std::runtime_error( "Failed to create record" ) ; | 17 throw windows_api_error( "MsiCreateRecord", 0 ) ; |
17 } | 18 } |
18 } | 19 } |
19 | 20 |
20 Record::~Record() | 21 Record::~Record() |
21 { | 22 { |
22 if ( _handle != 0 ) | 23 if ( _handle != 0 ) |
23 { | 24 { |
24 MsiCloseHandle( _handle ) ; | 25 MsiCloseHandle( _handle ) ; |
25 } | 26 } |
26 } | 27 } |
(...skipping 17 matching lines...) Expand all Loading... | |
44 only_non_null() ; | 45 only_non_null() ; |
45 MsiRecordSetStringW( _handle, field_index, value ) ; | 46 MsiRecordSetStringW( _handle, field_index, value ) ; |
46 } | 47 } |
47 | 48 |
48 /** | 49 /** |
49 * \par Implementation | 50 * \par Implementation |
50 * - MSDN [MsiRecordGetString](http://msdn.microsoft.com/en-us/library/aa3703 68%28v=vs.85%29.aspx) | 51 * - MSDN [MsiRecordGetString](http://msdn.microsoft.com/en-us/library/aa3703 68%28v=vs.85%29.aspx) |
51 */ | 52 */ |
52 std::wstring Record::value_string( unsigned int field_index ) | 53 std::wstring Record::value_string( unsigned int field_index ) |
53 { | 54 { |
54 static wchar_t initial_buffer[ 256 ] = L"" ; | 55 static wchar_t initial_buffer[ 1024 ] = L"" ; |
55 DWORD length = 255 ; // one less than the buffer length to hold a terminating null character | 56 DWORD length = 1023 ; // one less than the buffer length to hold a terminating null character |
56 UINT x = MsiRecordGetStringW( _handle, field_index, initial_buffer, & length ) ; | 57 UINT x = MsiRecordGetStringW( _handle, field_index, initial_buffer, & length ) ; |
57 if ( x == ERROR_SUCCESS ) | 58 if ( x == ERROR_SUCCESS ) |
58 { | 59 { |
59 return std::wstring( initial_buffer ) ; | 60 return std::wstring( initial_buffer ) ; |
60 } | 61 } |
61 if ( x == ERROR_MORE_DATA ) | 62 if ( x == ERROR_MORE_DATA ) |
62 { | 63 { |
63 // Future: handle longer strings. | 64 // Future: handle longer strings. |
64 throw std::runtime_error( "Record strings longer than 255 not supported yet" ) ; | 65 /* |
66 * The present custom action only uses this function for strings that appear in dialog boxes. | |
67 * A thousand characters is about a dozen lines of text, which is far more t han enough. | |
68 */ | |
69 throw not_yet_supported( "retrieving string values longer than 1023 from a r ecord" ) ; | |
Oleksandr
2014/03/31 07:35:49
Still, why not just dynamically allocate the buffe
Eric
2014/03/31 11:23:09
It wouldn't. The main reason is that we have no ne
| |
65 } | 70 } |
66 throw std::runtime_error( "Error retrieving string from record" ) ; | 71 throw windows_api_error( "MsiRecordGetStringW", x ) ; |
67 } | 72 } |
68 | 73 |
69 size_t Record::n_fields() const | 74 size_t Record::n_fields() const |
70 { | 75 { |
71 unsigned int x = MsiRecordGetFieldCount( _handle ) ; | 76 unsigned int x = MsiRecordGetFieldCount( _handle ) ; |
72 if ( x == 0xFFFFFFFF ) | 77 if ( x == 0xFFFFFFFF ) |
73 { | 78 { |
74 throw std::runtime_error( "Invalid handle" ) ; | 79 throw windows_api_error( "MsiRecordGetFieldCount", x, "invalid handle" ) ; |
75 } | 80 } |
76 return x ; | 81 return x ; |
77 } | 82 } |
OLD | NEW |