void _clear_act_list( ) { list_entry *node = __action.flink; list_entry *del = NULL; list_entry *head = &__action; for ( ; node != &__action; ) { _dact *act = contain_record(node, _dact, list); if ( ACT_STOPPED == act->status ) { if ( WaitForSingleObject(act->h_thread, 0) == WAIT_OBJECT_0 ) { del = node; node = node->flink; _remove_entry_list(del); CloseHandle(act->h_thread); free(del); continue; } } node = node->flink; } }
void FreeList(list_entry* head){ list_entry* entry; entry = head->next; while(entry != head){ EEListItem *item = contain_record(entry, EEListItem, list); remove(entry); (*item->finalizer)((void*)item->value); _tsfree(item); entry = head->next; } }
void RemoveVarFromTable(EEVarTable* table, const _tsstr name){ TSStr* str; list_entry *list, *entry; EEVar* var; str = StrCreate(); StrAppendS(str, name); list = &table->table[table->hash(str)]; StrDestroy(str); for_each(list, entry){ if( !_tsstrcmp(contain_record(entry, EEVar, vlist)->name, name) ) break; } if( entry != list ){ remove(entry); var = contain_record(entry, EEVar, vlist); /*we need to free the space owned by this entry and its value*/ FreeEEObject(var->value.type, (void*)var->value.value); _tsfree(var);/*finally, free the var object;*/ } }
static int dc_mount_parts() { dc_header *header = pv(0x5000); /* free memory location */ dc_key *hdr_key = pv(0x5000 + sizeof(dc_header)); list_entry *entry; prt_inf *prt; int n_mount; /* mount partitions on all disks */ n_mount = 0; entry = prt_head.flink; while ( (entry != &prt_head) && (n_mount < MAX_MOUNT) ) { prt = contain_record(entry, prt_inf, entry_glb); entry = entry->flink; do { /* read volume header */ if (dc_partition_io(prt, header, DC_AREA_SECTORS, 0, 1) == 0) { break; } if (dc_decrypt_header(hdr_key, header, &bd_dat->password) == 0) { break; } if (header->flags & VF_REENCRYPT) { prt->o_key.key_d = malloc(PKCS_DERIVE_MAX); autocpy(prt->o_key.key_d, header->key_2, PKCS_DERIVE_MAX); } prt->d_key.key_d = malloc(PKCS_DERIVE_MAX); autocpy(prt->d_key.key_d, header->key_1, PKCS_DERIVE_MAX); prt->flags = header->flags; prt->tmp_size = header->tmp_size / SECTOR_SIZE; prt->stor_off = header->stor_off / SECTOR_SIZE; prt->disk_id = header->disk_id; prt->d_key.alg = header->alg_1; prt->o_key.alg = header->alg_2; prt->mnt_ok = 1; n_mount++; } while (0); } /* prevent leaks */ zeroauto(header, sizeof(dc_header)); zeroauto(hdr_key, sizeof(dc_key)); return n_mount; }
void EERun( EEProgram* program){ EEInst* end; g_context->program = program; g_context->currentFunc = &program->global; g_context->ip = program->entry; g_context->callstack->function = &program->global; g_context->callstack->retAddr = null; end = contain_record(&program->global.ilist, EEInst, list); while(g_context->ip != end){ (g_context->ip->func)(g_context->ip->regv, g_context->ip->regc); } }
EEVar* FindVarInTable(EEVarTable* table, const _tsstr name) /** Retrieve a EEVar object from the specified in hash table EEVarTable object with name specified. If any can be found, return the EEVar pointer else return NULL */ { TSStr* str; EEVar* result = NULL; list_entry *list,*entry; str = StrCreate(); StrAppendS(str, name); list = &table->table[table->hash(str)]; StrDestroy(str); for_each(list, entry){ if(! _tsstrcmp(contain_record(entry, EEVar, vlist)->name, name)){ result = contain_record(entry, EEVar, vlist); break; } } return result; }
void DeleteVarList(list_entry* head){ list_entry* entry; entry = head->next; while(entry != head){ EEVar* var = contain_record(entry, EEVar, vlist); remove(entry); entry = entry->next; /*we need to free the space owned by this entry and its value*/ FreeEEObject(var->value.type, var->value.value); _tsfree(var);/*finally, free the var object;*/ } init_list(head); }
_list_key_files *_first_keyfile(int key_list) { list_entry *head = _KEYFILES_HEAD_(key_list); _list_key_files *keyfile; if ( _is_list_empty(head) == FALSE ) { keyfile = contain_record(head->flink, _list_key_files, next); } else { keyfile = NULL; } return keyfile; }
void ResetVarTable(EEVarTable* table){ int i = 0; for(; i < HASH_TABLE_SIZE; ++i){ list_entry* entry; list_entry* head = &table->table[i]; entry = head->next; while(entry != head){ EEVar* var = contain_record(entry, EEVar, vlist); var->value.value = 0; var->value.type = 0; entry = entry->next; } init_list(head); } }
_list_key_files *_next_keyfile( _list_key_files *keyfile, int key_list ) { _list_key_files *next; if ( keyfile->next.flink != _KEYFILES_HEAD_(key_list) ) { next = contain_record( keyfile->next.flink, _list_key_files, next ); } else { next = NULL; } return next; }
/* find first HDD contain active partition */ static hdd_inf *find_bootable_hdd() { list_entry *entry; prt_inf *prt; entry = prt_head.flink; while (entry != &prt_head) { prt = contain_record(entry, prt_inf, entry_glb); entry = entry->flink; if ( (prt->active != 0) && ( !(conf.options & OP_EXTERNAL) || (prt->hdd->dos_numb != boot_dsk) ) ) { return prt->hdd; } } return NULL; }
void _is_breaking_action( ) { list_entry *node; list_entry *sub; int count = 0; int k, flag; BOOL resume; wchar_t s_vol[MAX_PATH] = { 0 }; for ( k = 0; k < 4; k++ ) { if (k % 2 == 0) { memset(s_vol, 0, sizeof_w(s_vol)); // WTF? count = 0; resume = FALSE; } for ( node = __drives.flink; node != &__drives; node = node->flink ) { _dnode *root = contain_record(node, _dnode, list); for ( sub = root->root.vols.flink; sub != &root->root.vols; sub = sub->flink ) { _dnode *mnt = contain_record(sub, _dnode, list); switch (k) { case 0: case 1: flag = F_FORMATTING; break; case 2: case 3: flag = F_SYNC; break; default: flag = -1; break; } if (mnt->mnt.info.status.flags & flag) { if (k % 2 == 0) { if (s_vol[0] != L'\0') wcscat(s_vol, L", "); wcscat(s_vol, mnt->mnt.info.status.mnt_point); count++; } else { if (resume) { if (k == 1) _menu_format(mnt); if (k == 3) _menu_encrypt(mnt); } } } } } if ((k % 2 == 0) && count > 0) { if (__msg_q( __dlg, L"%s was suspended for volume%s %s.\n\n" L"Continue %s?", k != 0 ? L"Encrypting/decrypting" : L"Formatting", count > 1 ? L"s" : STR_NULL, s_vol, k != 0 ? L"encrypting" : L"formatting") ) { resume = TRUE; } } } }
void _add_drive_node( _dnode *exist_node, drive_inf *new_drv, vol_inf *vol, int disk_number ) { wchar_t drvname[MAX_PATH]; wchar_t fs[MAX_PATH] = { 0 }; wchar_t label[MAX_PATH] = { 0 }; wchar_t path[MAX_PATH]; list_entry *node; BOOL root_exists = FALSE; _dnode *root; _dnode *mnt; mnt = exist_node; if ( mnt == NULL ) { mnt = malloc( sizeof(_dnode) ); memset( mnt, 0, sizeof(_dnode) ); } mnt->exists = TRUE; memcpy( &mnt->mnt.info, vol, sizeof(vol_inf) ); _snwprintf( path, sizeof_w(path), L"%s\\", vol->status.mnt_point ); GetVolumeInformation( path, label, sizeof_w(label), 0, 0, 0, fs, sizeof_w(fs) ); wcscpy( mnt->mnt.label, label ); wcscpy( mnt->mnt.fs, fs ); if (! exist_node ) { dc_get_hw_name( disk_number, vol->status.flags & F_CDROM, drvname, sizeof_w(drvname) ); if (! ( vol->status.flags & F_CDROM ) ) { for ( node = __drives.flink; node != &__drives; node = node->flink ) { root = contain_record(node, _dnode, list); if ( root->root.dsk_num == disk_number ) { root_exists = TRUE; break; } } } mnt->is_root = FALSE; memcpy( &mnt->root.info, new_drv, sizeof(drive_inf) ); if (! root_exists ) { root = malloc(sizeof(_dnode)); root->is_root = TRUE; memcpy(&root->mnt.info, vol, sizeof(vol_inf)); memcpy(&root->root.info, new_drv, sizeof(drive_inf)); wcscpy(root->root.dsk_name, drvname); root->root.dsk_num = disk_number; _init_list_head(&root->root.vols); _insert_tail_list(&__drives, &root->list); } _insert_tail_list(&root->root.vols, &mnt->list); } if ( vol->status.flags & F_SYNC && _create_act_thread(mnt, -1, -1) == NULL ) { _create_act_thread(mnt, ACT_ENCRYPT, ACT_PAUSED); } }
_dnode *_scan_vols_tree( vol_inf *vol, int *count ) { list_entry *del; list_entry *node; list_entry *sub; for ( node = __drives.flink; node != &__drives ; ) { _dnode *root = contain_record(node, _dnode, list); if ( count ) { *count += 1; } for ( sub = root->root.vols.flink; sub != &root->root.vols ; ) { _dnode *mnt = contain_record(sub, _dnode, list); if ( count ) { *count += 1; } if (! vol ) { if (! mnt->exists ) { del = sub; sub = sub->flink; _remove_entry_list(del); free(del); continue; } } else { if ( ( wcscmp(mnt->mnt.info.device, vol->device) == 0 ) && (! mnt->exists) ) { return mnt; } } sub = sub->flink; } if (_is_list_empty(sub)) { del = node; node = node->flink; _remove_entry_list(del); free(del); continue; } node = node->flink; } return NULL; }
_dact *_create_act_thread( _dnode *node, int act_type, // -1 - search int act_status // ) { list_entry *item; _dact *act; DWORD resume; BOOL exist = FALSE; if ( !node ) { return NULL; } _clear_act_list( ); for ( item = __action.flink; item != &__action; item = item->flink ) { act = contain_record(item, _dact, list); if ( !wcscmp(act->device, node->mnt.info.device) ) { exist = TRUE; if ( act_type == -1 ) { return act; } else { break; } } } if ( act_type != -1 ) { if ( !exist ) { act = malloc(sizeof(_dact)); memset(act, 0, sizeof(_dact)); act->wp_mode = node->mnt.info.status.crypt.wp_mode; wcsncpy( act->device, node->mnt.info.device, MAX_PATH ); _init_speed_stat( &act->speed ); } act->h_thread = NULL; act->status = act_status; act->act = act_type; if ( act_status == ACT_RUNNING ) { void *proc; switch (act_type) { case ACT_REENCRYPT: case ACT_ENCRYPT: case ACT_DECRYPT: proc = _thread_enc_dec_proc; break; case ACT_FORMAT: proc = _thread_format_proc; break; } act->h_thread = CreateThread( NULL, 0, proc, pv(node), CREATE_SUSPENDED, NULL ); SetThreadPriority(act->h_thread, THREAD_PRIORITY_LOWEST); resume = ResumeThread(act->h_thread); if ( !act->h_thread || resume == (DWORD)-1 ) { free(act); __error_s( __dlg, L"Error create thread", -1 ); return NULL; } } if ( !exist ) { _insert_tail_list(&__action, &act->list); } return act; } return NULL; }
void boot_main() { list_entry *entry; hdd_inf *hdd; prt_inf *prt, *active; char *error; int login, i; int n_mount; active = NULL; error = NULL; login = 0; n_mount = 0; /* init crypto */ dc_init_crypto(conf.options & OP_HW_CRYPTO); /* prepare MBR copy buffer */ autocpy(conf.save_mbr + 432, p8(0x7C00) + 432, 80); if (dc_scan_partitions() == 0) { error = "partitions not found\n"; goto error; } if (hdd = find_hdd(boot_dsk)) { /* find active partition on boot disk */ entry = hdd->part_head.flink; while (entry != &hdd->part_head) { prt = contain_record(entry, prt_inf, entry_hdd); entry = entry->flink; if (prt->active != 0) { active = prt; break; } } } retry_auth:; if (conf.logon_type & LT_GET_PASS) { login = dc_get_password(); if ( (conf.options & OP_NOPASS_ERROR) && (login == 0) ) { dc_password_error(active); if (conf.error_type & ET_RETRY) { goto retry_auth; } else { /* halt system */ __halt(); } } } /* add embedded keyfile to password buffer */ if (conf.logon_type & LT_EMBED_KEY) { sha512_ctx sha; u8 hash[SHA512_DIGEST_SIZE]; sha512_init(&sha); sha512_hash(&sha, conf.emb_key, sizeof(conf.emb_key)); sha512_done(&sha, hash); /* mix the keyfile hash and password */ for (i = 0; i < (SHA512_DIGEST_SIZE / sizeof(u32)); i++) { p32(bd_dat->password.pass)[i] += p32(hash)[i]; } bd_dat->password.size = max(bd_dat->password.size, SHA512_DIGEST_SIZE); /* prevent leaks */ zeroauto(hash, sizeof(hash)); zeroauto(&sha, sizeof(sha)); } if (bd_dat->password.size != 0) { if (n_mount = dc_mount_parts()) { /* hook BIOS interrupts */ bios_hook_ints(); } else { /* clean password buffer to prevent leaks */ zeroauto(&bd_dat->password, sizeof(dc_pass)); } } if ( (n_mount == 0) && (login != 0) ) { dc_password_error(active); if (conf.error_type & ET_RETRY) { goto retry_auth; } else { /* halt system */ __halt(); } } switch (conf.boot_type) { case BT_MBR_BOOT: { if (hdd == NULL) { error = "boot disk not found\n"; goto error; } boot_from_mbr(hdd, n_mount); } break; case BT_MBR_FIRST: { if ( (hdd = find_bootable_hdd()) == NULL ) { error = "boot disk not found\n"; goto error; } boot_from_mbr(hdd, n_mount); } break; case BT_ACTIVE: { if (active == NULL) { error = "active partition not found\n"; goto error; } else { boot_from_partition(active, n_mount); } } break; case BT_AP_PASSWORD: { /* find first partition with appropriate password */ entry = prt_head.flink; while (entry != &prt_head) { prt = contain_record(entry, prt_inf, entry_glb); entry = entry->flink; if ( (prt->extend == 0) && (prt->mnt_ok != 0) ) { boot_from_partition(prt, n_mount); } } error = "bootable partition not mounted\n"; goto error; } break; case BT_DISK_ID: { /* find partition by disk_id */ entry = prt_head.flink; while (entry != &prt_head) { prt = contain_record(entry, prt_inf, entry_glb); entry = entry->flink; if ( (prt->extend == 0) && (prt->mnt_ok != 0) && (prt->disk_id == conf.disk_id) ) { boot_from_partition(prt, n_mount); } } error = "disk_id equal partition not found\n"; goto error; } break; } error:; if (error != NULL) { puts(error); } while (1); }