OLD | NEW |
1 /** | 1 /** |
2 * \file record.cpp Implementation of Session 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 : n_fields( n_fields ) | |
13 { | 13 { |
14 _handle = MsiCreateRecord( n_fields ) ; | 14 _handle = MsiCreateRecord( n_fields ) ; |
15 if ( ! _handle ) | 15 if ( ! _handle ) |
16 { | 16 { |
17 throw std::runtime_error( "Failed to create record" ) ; | 17 throw windows_api_error( "MsiCreateRecord", 0 ) ; |
18 } | 18 } |
19 } | 19 } |
20 | 20 |
21 Record::~Record() | 21 Record::~Record() |
22 { | 22 { |
23 MsiCloseHandle( _handle ) ; | 23 if ( _handle != 0 ) |
| 24 { |
| 25 MsiCloseHandle( _handle ) ; |
| 26 } |
24 } | 27 } |
25 | 28 |
26 void | 29 void Record::only_non_null() |
27 Record::assign_string( unsigned int field_index, std::wstring value ) | |
28 { | 30 { |
29 MsiRecordSetString( _handle, field_index, value.c_str() ) ; | 31 if ( _handle == 0 ) |
| 32 { |
| 33 throw std::runtime_error( "Operation only permitted for non-null objects" )
; |
| 34 } |
| 35 } |
| 36 |
| 37 void Record::assign_string( unsigned int field_index, const char *value ) |
| 38 { |
| 39 only_non_null() ; |
| 40 MsiRecordSetStringA( _handle, field_index, value ) ; |
| 41 } |
| 42 |
| 43 void Record::assign_string( unsigned int field_index, const wchar_t *value ) |
| 44 { |
| 45 only_non_null() ; |
| 46 MsiRecordSetStringW( _handle, field_index, value ) ; |
| 47 } |
| 48 |
| 49 /** |
| 50 * \par Implementation |
| 51 * - MSDN [MsiRecordGetString](http://msdn.microsoft.com/en-us/library/aa37036
8%28v=vs.85%29.aspx) |
| 52 */ |
| 53 std::wstring Record::value_string( unsigned int field_index ) |
| 54 { |
| 55 static wchar_t initial_buffer[ 1024 ] = L"" ; |
| 56 DWORD length = 1023 ; // one less than the buffer length to hold a terminating
null character |
| 57 UINT x = MsiRecordGetStringW( _handle, field_index, initial_buffer, & length )
; |
| 58 if ( x == ERROR_SUCCESS ) |
| 59 { |
| 60 return std::wstring( initial_buffer ) ; |
| 61 } |
| 62 if ( x == ERROR_MORE_DATA ) |
| 63 { |
| 64 // Future: handle longer strings. |
| 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 th
an enough. |
| 68 */ |
| 69 throw not_yet_supported( "retrieving string values longer than 1023 from a r
ecord" ) ; |
| 70 } |
| 71 throw windows_api_error( "MsiRecordGetStringW", x ) ; |
| 72 } |
| 73 |
| 74 size_t Record::n_fields() const |
| 75 { |
| 76 unsigned int x = MsiRecordGetFieldCount( _handle ) ; |
| 77 if ( x == 0xFFFFFFFF ) |
| 78 { |
| 79 throw windows_api_error( "MsiRecordGetFieldCount", x, "invalid handle" ) ; |
| 80 } |
| 81 return x ; |
30 } | 82 } |
OLD | NEW |