/** * gck_attribute_init: * @attr: An uninitialized attribute. * @attr_type: The PKCS#11 attribute type to set on the attribute. * @value: The raw value of the attribute. * @length: The length of the raw value. * * Initialize a PKCS#11 attribute. This copies the value memory * into an internal buffer. * * When done with the attribute you should use gck_attribute_clear() * to free the internal memory. **/ void gck_attribute_init (GckAttribute *attr, gulong attr_type, gconstpointer value, gsize length) { g_return_if_fail (attr); attribute_init (attr, attr_type, value, length, g_realloc); }
/** * gck_attribute_new: * @attr_type: The PKCS#11 attribute type to set on the attribute. * @value: The raw value of the attribute. * @length: The length of the attribute. * * Create a new PKCS#11 attribute. The value will be copied * into the new attribute. * * Return value: The new attribute. When done with the attribute use * gck_attribute_free() to free it. **/ GckAttribute* gck_attribute_new (gulong attr_type, gpointer value, gsize length) { GckAttribute *attr = g_slice_new0 (GckAttribute); attribute_init (attr, attr_type, value, length, g_realloc); return attr; }
static void attribute_init_string (GckAttribute *attr, gulong attr_type, const gchar *value, GckAllocator allocator) { gsize len = value ? strlen (value) : 0; attribute_init (attr, attr_type, (gpointer)value, len, allocator); }
static void attribute_init_ulong (GckAttribute *attr, gulong attr_type, gulong value, GckAllocator allocator) { CK_ULONG uvalue = value; attribute_init (attr, attr_type, &uvalue, sizeof (uvalue), allocator); }
static void attribute_init_boolean (GckAttribute *attr, gulong attr_type, gboolean value, GckAllocator allocator) { CK_BBOOL bvalue = value ? CK_TRUE : CK_FALSE; attribute_init (attr, attr_type, &bvalue, sizeof (bvalue), allocator); }
/** * gck_attributes_add_data: * @attrs: The attributes array to add to. * @attr_type: The type of attribute to add. * @value: The raw memory of the attribute value. * @length: The length of the attribute value. * * Add an attribute with the specified type and value to the array. * * The value stored in the attribute will be copied. * * Return value: The attribute that was added. **/ GckAttribute* gck_attributes_add_data (GckAttributes *attrs, gulong attr_type, gconstpointer value, gsize length) { GckAttribute *added; g_return_val_if_fail (attrs, NULL); g_return_val_if_fail (!attrs->locked, NULL); added = attributes_push (attrs); attribute_init (added, attr_type, value, length, attrs->allocator); return added; }
static void attribute_init_date (GckAttribute *attr, gulong attr_type, const GDate *value, GckAllocator allocator) { gchar buffer[9]; CK_DATE date; g_assert (value); g_snprintf (buffer, sizeof (buffer), "%04d%02d%02d", (int)g_date_get_year (value), (int)g_date_get_month (value), (int)g_date_get_day (value)); memcpy (&date.year, buffer + 0, 4); memcpy (&date.month, buffer + 4, 2); memcpy (&date.day, buffer + 6, 2); attribute_init (attr, attr_type, &date, sizeof (CK_DATE), allocator); }
void mft_record_t::mft_record_init(const char *buffer) { const static char f_name[] = "mft_record_init()"; // Псевдо имя функции enum {INIT, IS_STATE1, IS_STATE2, IS_STATE3, IS_STATE4, IS_MEM} state = INIT; bool ok = true; const u32_t bytes_per_mft_record = partition->get_bytes_per_mft_record(); // находим константы total_attributes = 0; // колличество атрибутог if( ok ) { // считываем заголовок header.offset_to_update_sequence = *(u16_t*)(buffer + mr_offset_to_update_sequence); header.size_of_update_sequence = *(u16_t*)(buffer + mr_size_of_update_sequence); header.logfile_sequence_number = *(u64_t*)(buffer + mr_logfile_sequence_number); header.sequence_number = *(u16_t*)(buffer + mr_sequence_number); header.hard_link_count = *(u16_t*)(buffer + mr_hard_link_count); header.offset_to_first_attribute = *(u16_t*)(buffer + mr_offset_to_first_attribute); header.flags = *(u16_t*)(buffer + mr_flags); header.reference_to_base_mft_record = *(u64_t*)(buffer + mr_reference_to_base_mft_record); header.next_attribute_ID = *(u16_t*)(buffer + mr_next_attribute_ID); header.update_sequence_number = *(u16_t*)(buffer + *(u16_t*)(buffer + mr_offset_to_update_sequence)); } if( ok ) { // проходим по списку атрибутов, считаем, проверяем упорядоченность u32_t type = 0; u32_t off = header.offset_to_first_attribute; while( ok ) { u32_t att_record_lenght = *(u32_t*)(buffer + off + ah_attribute_record_lenght); if( ok ) { // проверяем упорядоченность списка атрибутов state = IS_STATE1; ok = (type <= *(u32_t*)(buffer + off + ah_attribute_type)); } if( ok ) // считываем тип атрибута type = *(u32_t*)(buffer + off + ah_attribute_type); if( ok && attrib_end_of_attributes == type ) // если это специальный атрибут, обрываем поиск break; if( ok ) { // смещение не должно быть нулевым state = IS_STATE2; ok = (0 != att_record_lenght); } if( ok ) { // смещение не должно быть слишком большим state = IS_STATE3; ok = (att_record_lenght <= bytes_per_mft_record - 2*sizeof(u32_t) - off); } if( ok ) // пересчитываем смещение off += att_record_lenght; ++total_attributes; } } if( ok ) { // атрибутов должно быть не пуст state = IS_STATE4; ok = (total_attributes > 0); } if( ok ) { // выделяем память под атрибуты state = IS_MEM; ok = (NULL != (attributes = (struct attribute_t **)malloc(total_attributes*sizeof(struct attribute_t *)))); } u32_t off; // смещение атрибута if( ok ) { // считываем список атрибутов off = header.offset_to_first_attribute; u32_t i = 0; do { try { struct attribute_t att; attribute_init(&att, buffer + off, num_of_mft_record, off); state = IS_MEM; ok = (NULL != (attributes[i] = (struct attribute_t *)malloc(sizeof(struct attribute_t)))); if( ok ) memcpy(attributes[i], &att, sizeof(struct attribute_t)); } catch(bool) { attributes[i] = NULL; } off += *(u32_t*)(buffer + off + ah_attribute_record_lenght); ++i; } while( ok && i < total_attributes ); } if( ok ) return; switch( state ) { case IS_STATE1: fprintf(stderr, "%s: mft-запись 0x%llx: список атрибутов не упорядочен.\n", f_name, num_of_mft_record); break; case IS_STATE2: fprintf(stderr, "%s: mft-запись 0x%llx: атрибут по смещению 0x%llx имеет нулевой размер.\n", f_name, num_of_mft_record, off); break; case IS_STATE3: fprintf(stderr, "%s: mft-запись 0x%llx: атрибут по смещению 0x%llx имеет заведомо слишком большой размер.\n", f_name, num_of_mft_record, off); break; case IS_STATE4: fprintf(stderr, "%s: mft-запись 0x%llx: список атрибутов пуст.\n", f_name, num_of_mft_record); break; case IS_MEM: fprintf(stderr, "%s: %s\n", f_name, strerror(errno)); exit(-1); default: assert( 0 ); } throw false; }