データ構造 | |
struct | regf_hbin |
struct | REGF_HASH_REC |
struct | REGF_LF_REC |
struct | REGF_VK_REC |
struct | _regf_sk_rec |
struct | REGF_NK_REC |
struct | REGF_FILE |
型定義 | |
typedef regf_hbin | REGF_HBIN |
typedef _regf_sk_rec | REGF_SK_REC |
関数 | |
REGF_FILE * | regfio_open (const char *filename, int flags, int mode) |
int | regfio_close (REGF_FILE *r) |
REGF_NK_REC * | regfio_rootkey (REGF_FILE *file) |
REGF_NK_REC * | regfio_fetch_subkey (REGF_FILE *file, REGF_NK_REC *nk) |
REGF_NK_REC * | regfio_write_key (REGF_FILE *file, const char *name, REGVAL_CTR *values, REGSUBKEY_CTR *subkeys, SEC_DESC *sec_desc, REGF_NK_REC *parent) |
typedef struct _regf_sk_rec REGF_SK_REC |
REGF_FILE* regfio_open | ( | const char * | filename, | |
int | flags, | |||
int | mode | |||
) |
参照先 errno・REGF_FILE::fd・init_regf_block()・REGF_FILE::mem_ctx・REGF_FILE::open_flags・read_regf_block()・regfio_close()・strerror()・talloc_init().
参照元 backup_registry_key()・main()・restore_registry_key()・rpc_registry_copy()・rpc_registry_dump().
01160 { 01161 REGF_FILE *rb; 01162 01163 if ( !(rb = SMB_MALLOC_P(REGF_FILE)) ) { 01164 DEBUG(0,("ERROR allocating memory\n")); 01165 return NULL; 01166 } 01167 ZERO_STRUCTP( rb ); 01168 rb->fd = -1; 01169 01170 if ( !(rb->mem_ctx = talloc_init( "read_regf_block" )) ) { 01171 regfio_close( rb ); 01172 return NULL; 01173 } 01174 01175 rb->open_flags = flags; 01176 01177 /* open and existing file */ 01178 01179 if ( (rb->fd = open(filename, flags, mode)) == -1 ) { 01180 DEBUG(0,("regfio_open: failure to open %s (%s)\n", filename, strerror(errno))); 01181 regfio_close( rb ); 01182 return NULL; 01183 } 01184 01185 /* check if we are creating a new file or overwriting an existing one */ 01186 01187 if ( flags & (O_CREAT|O_TRUNC) ) { 01188 if ( !init_regf_block( rb ) ) { 01189 DEBUG(0,("regfio_open: Failed to read initial REGF block\n")); 01190 regfio_close( rb ); 01191 return NULL; 01192 } 01193 01194 /* success */ 01195 return rb; 01196 } 01197 01198 /* read in an existing file */ 01199 01200 if ( !read_regf_block( rb ) ) { 01201 DEBUG(0,("regfio_open: Failed to read initial REGF block\n")); 01202 regfio_close( rb ); 01203 return NULL; 01204 } 01205 01206 /* success */ 01207 01208 return rb; 01209 }
int regfio_close | ( | REGF_FILE * | r | ) |
参照先 REGF_FILE::block_list・REGF_FILE::checksum・fd・REGF_FILE::fd・_regf_sk_rec::hbin・hbin_block_close()・hbin_prs_sk_rec()・REGF_FILE::mtime・_regf_sk_rec::next・REGF_FILE::open_flags・prs_mem_free()・prs_regf_block()・read_block()・regf_block_checksum()・regfio_mem_free()・REGF_FILE::sec_desc_list・unix_to_nt_time()・write_block().
参照元 backup_registry_key()・main()・regfio_open()・restore_registry_key()・rpc_registry_copy()・rpc_registry_dump().
01226 { 01227 int fd; 01228 01229 /* cleanup for a file opened for write */ 01230 01231 if ( file->open_flags & (O_WRONLY|O_RDWR) ) { 01232 prs_struct ps; 01233 REGF_SK_REC *sk; 01234 01235 /* write of sd list */ 01236 01237 for ( sk=file->sec_desc_list; sk; sk=sk->next ) { 01238 hbin_prs_sk_rec( "sk_rec", sk->hbin, 0, sk ); 01239 } 01240 01241 /* flush any dirty blocks */ 01242 01243 while ( file->block_list ) { 01244 hbin_block_close( file, file->block_list ); 01245 } 01246 01247 ZERO_STRUCT( ps ); 01248 01249 unix_to_nt_time( &file->mtime, time(NULL) ); 01250 01251 if ( read_block( file, &ps, 0, REGF_BLOCKSIZE ) != -1 ) { 01252 /* now use for writing */ 01253 prs_switch_type( &ps, MARSHALL ); 01254 01255 /* stream the block once, generate the checksum, 01256 and stream it again */ 01257 prs_set_offset( &ps, 0 ); 01258 prs_regf_block( "regf_blocK", &ps, 0, file ); 01259 file->checksum = regf_block_checksum( &ps ); 01260 prs_set_offset( &ps, 0 ); 01261 prs_regf_block( "regf_blocK", &ps, 0, file ); 01262 01263 /* now we are ready to write it to disk */ 01264 if ( write_block( file, &ps, 0 ) == -1 ) 01265 DEBUG(0,("regfio_close: failed to update the regf header block!\n")); 01266 } 01267 01268 prs_mem_free( &ps ); 01269 } 01270 01271 regfio_mem_free( file ); 01272 01273 /* nothing tdo do if there is no open file */ 01274 01275 if ( !file || (file->fd == -1) ) 01276 return 0; 01277 01278 fd = file->fd; 01279 file->fd = -1; 01280 SAFE_FREE( file ); 01281 01282 return close( fd ); 01283 }
REGF_NK_REC* regfio_rootkey | ( | REGF_FILE * | file | ) |
参照先 REGF_FILE::block_list・regf_hbin::block_size・REGF_NK_REC::key_type・REGF_FILE::mem_ctx・next_nk_record()・prs_mem_free()・regf_hbin::ps・read_hbin_block().
参照元 main()・restore_registry_key()・rpc_registry_copy()・rpc_registry_dump().
01303 { 01304 REGF_NK_REC *nk; 01305 REGF_HBIN *hbin; 01306 uint32 offset = REGF_BLOCKSIZE; 01307 BOOL found = False; 01308 BOOL eob; 01309 01310 if ( !file ) 01311 return NULL; 01312 01313 if ( !(nk = TALLOC_ZERO_P( file->mem_ctx, REGF_NK_REC )) ) { 01314 DEBUG(0,("regfio_rootkey: talloc() failed!\n")); 01315 return NULL; 01316 } 01317 01318 /* scan through the file on HBIN block at a time looking 01319 for an NK record with a type == 0x002c. 01320 Normally this is the first nk record in the first hbin 01321 block (but I'm not assuming that for now) */ 01322 01323 while ( (hbin = read_hbin_block( file, offset )) ) { 01324 eob = False; 01325 01326 while ( !eob) { 01327 if ( next_nk_record( file, hbin, nk, &eob ) ) { 01328 if ( nk->key_type == NK_TYPE_ROOTKEY ) { 01329 found = True; 01330 break; 01331 } 01332 } 01333 prs_mem_free( &hbin->ps ); 01334 } 01335 01336 if ( found ) 01337 break; 01338 01339 offset += hbin->block_size; 01340 } 01341 01342 if ( !found ) { 01343 DEBUG(0,("regfio_rootkey: corrupt registry file ? No root key record located\n")); 01344 return NULL; 01345 } 01346 01347 DLIST_ADD( file->block_list, hbin ); 01348 01349 return nk; 01350 }
REGF_NK_REC* regfio_fetch_subkey | ( | REGF_FILE * | file, | |
REGF_NK_REC * | nk | |||
) |
参照先 regf_hbin::first_hbin_off・REGF_LF_REC::hashes・hbin_prs_key()・lookup_hbin_block()・REGF_FILE::mem_ctx・REGF_HASH_REC::nk_off・REGF_NK_REC::num_subkeys・regf_hbin::ps・REGF_NK_REC::subkey_index・REGF_NK_REC::subkeys・REGF_NK_REC::subkeys_off.
参照元 copy_registry_tree()・dump_registry_tree()・reg_load_tree()・write_registry_tree().
01358 { 01359 REGF_NK_REC *subkey; 01360 REGF_HBIN *hbin; 01361 uint32 nk_offset; 01362 01363 /* see if there is anything left to report */ 01364 01365 if ( !nk || (nk->subkeys_off==REGF_OFFSET_NONE) || (nk->subkey_index >= nk->num_subkeys) ) 01366 return NULL; 01367 01368 /* find the HBIN block which should contain the nk record */ 01369 01370 if ( !(hbin = lookup_hbin_block( file, nk->subkeys.hashes[nk->subkey_index].nk_off )) ) { 01371 DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing offset [0x%x]\n", 01372 nk->subkeys.hashes[nk->subkey_index].nk_off)); 01373 return NULL; 01374 } 01375 01376 nk_offset = nk->subkeys.hashes[nk->subkey_index].nk_off; 01377 if ( !prs_set_offset( &hbin->ps, (HBIN_HDR_SIZE + nk_offset - hbin->first_hbin_off) ) ) 01378 return NULL; 01379 01380 nk->subkey_index++; 01381 if ( !(subkey = TALLOC_ZERO_P( file->mem_ctx, REGF_NK_REC )) ) 01382 return NULL; 01383 01384 if ( !hbin_prs_key( file, hbin, subkey ) ) 01385 return NULL; 01386 01387 return subkey; 01388 }
REGF_NK_REC* regfio_write_key | ( | REGF_FILE * | file, | |
const char * | name, | |||
REGVAL_CTR * | values, | |||
REGSUBKEY_CTR * | subkeys, | |||
SEC_DESC * | sec_desc, | |||
REGF_NK_REC * | parent | |||
) |
参照先 REGF_NK_REC::classname・REGF_NK_REC::classname_off・create_vk_record()・regf_hbin::file_off・find_free_space()・find_sk_record_by_sec_desc()・regf_hbin::first_hbin_off・REGF_HASH_REC::fullname・REGF_LF_REC::hashes・hashrec_cmp()・REGF_NK_REC::hbin・REGF_LF_REC::hbin・_regf_sk_rec::hbin・REGF_VK_REC::hbin・REGF_NK_REC::hbin_off・_regf_sk_rec::hbin_off・REGF_LF_REC::hbin_off・REGF_VK_REC::hbin_off・hbin_prs_lf_records()・hbin_prs_vk_records()・REGF_NK_REC::header・_regf_sk_rec::header・REGF_LF_REC::header・REGF_NK_REC::key_type・REGF_HASH_REC::keycheck・REGF_NK_REC::keyname・lf_record_data_size()・REGF_NK_REC::max_bytes_subkeyname・REGF_NK_REC::max_bytes_value・REGF_NK_REC::max_bytes_valuename・REGF_FILE::mem_ctx・REGF_NK_REC::mtime・_regf_sk_rec::next_sk_off・REGF_HASH_REC::nk_off・nk_record_data_size()・REGF_LF_REC::num_keys・REGF_NK_REC::num_subkeys・REGF_NK_REC::num_values・REGF_NK_REC::parent_off・_regf_sk_rec::prev・_regf_sk_rec::prev_sk_off・prs_nk_rec()・regf_hbin::ps・REGF_VK_REC::rec_off・REGF_NK_REC::rec_size・_regf_sk_rec::rec_size・REGF_LF_REC::rec_size・REGF_VK_REC::rec_size・_regf_sk_rec::ref_count・regfio_flush()・regsubkey_ctr_numkeys()・regsubkey_ctr_specific_key()・regval_ctr_numvals()・regval_ctr_specific_value()・regval_name()・regval_size()・REGF_NK_REC::sec_desc・_regf_sk_rec::sec_desc・REGF_FILE::sec_desc_list・sec_desc_size()・size・_regf_sk_rec::size・REGF_NK_REC::sk_off・_regf_sk_rec::sk_off・sk_record_data_size()・REGF_NK_REC::subkey_index・REGF_NK_REC::subkeys・REGF_NK_REC::subkeys_off・talloc_strdup()・unix_to_nt_time()・values・REGF_NK_REC::values・REGF_NK_REC::values_off・vk_record_data_size().
参照元 copy_registry_tree()・reg_write_tree()・write_registry_tree().
01693 { 01694 REGF_NK_REC *nk; 01695 REGF_HBIN *vlist_hbin = NULL; 01696 uint32 size; 01697 01698 if ( !(nk = TALLOC_ZERO_P( file->mem_ctx, REGF_NK_REC )) ) 01699 return NULL; 01700 01701 memcpy( nk->header, "nk", REC_HDR_SIZE ); 01702 01703 if ( !parent ) 01704 nk->key_type = NK_TYPE_ROOTKEY; 01705 else 01706 nk->key_type = NK_TYPE_NORMALKEY; 01707 01708 /* store the parent offset (or -1 if a the root key */ 01709 01710 nk->parent_off = parent ? (parent->hbin_off + parent->hbin->file_off - REGF_BLOCKSIZE - HBIN_HDR_SIZE ) : REGF_OFFSET_NONE; 01711 01712 /* no classname currently */ 01713 01714 nk->classname_off = REGF_OFFSET_NONE; 01715 nk->classname = NULL; 01716 nk->keyname = talloc_strdup( file->mem_ctx, name ); 01717 01718 /* current modification time */ 01719 01720 unix_to_nt_time( &nk->mtime, time(NULL) ); 01721 01722 /* allocate the record on disk */ 01723 01724 size = nk_record_data_size( nk ); 01725 nk->rec_size = ( size - 1 ) ^ 0XFFFFFFFF; 01726 if ((nk->hbin = find_free_space( file, size )) == NULL) { 01727 return NULL; 01728 } 01729 nk->hbin_off = prs_offset( &nk->hbin->ps ); 01730 01731 /* Update the hash record in the parent */ 01732 01733 if ( parent ) { 01734 REGF_HASH_REC *hash = &parent->subkeys.hashes[parent->subkey_index]; 01735 01736 hash->nk_off = prs_offset( &nk->hbin->ps ) + nk->hbin->first_hbin_off - HBIN_HDR_SIZE; 01737 memcpy( hash->keycheck, name, sizeof(uint32) ); 01738 hash->fullname = talloc_strdup( file->mem_ctx, name ); 01739 parent->subkey_index++; 01740 01741 /* sort the list by keyname */ 01742 01743 qsort( parent->subkeys.hashes, parent->subkey_index, sizeof(REGF_HASH_REC), QSORT_CAST hashrec_cmp ); 01744 01745 if ( !hbin_prs_lf_records( "lf_rec", parent->subkeys.hbin, 0, parent ) ) 01746 return False; 01747 } 01748 01749 /* write the security descriptor */ 01750 01751 nk->sk_off = REGF_OFFSET_NONE; 01752 if ( sec_desc ) { 01753 uint32 sk_size = sk_record_data_size( sec_desc ); 01754 REGF_HBIN *sk_hbin; 01755 01756 /* search for it in the existing list of sd's */ 01757 01758 if ( (nk->sec_desc = find_sk_record_by_sec_desc( file, sec_desc )) == NULL ) { 01759 /* not found so add it to the list */ 01760 01761 if (!(sk_hbin = find_free_space( file, sk_size ))) { 01762 return NULL; 01763 } 01764 01765 if ( !(nk->sec_desc = TALLOC_ZERO_P( file->mem_ctx, REGF_SK_REC )) ) 01766 return NULL; 01767 01768 /* now we have to store the security descriptor in the list and 01769 update the offsets */ 01770 01771 memcpy( nk->sec_desc->header, "sk", REC_HDR_SIZE ); 01772 nk->sec_desc->hbin = sk_hbin; 01773 nk->sec_desc->hbin_off = prs_offset( &sk_hbin->ps ); 01774 nk->sec_desc->sk_off = prs_offset( &sk_hbin->ps ) + sk_hbin->first_hbin_off - HBIN_HDR_SIZE; 01775 nk->sec_desc->rec_size = (sk_size-1) ^ 0xFFFFFFFF; 01776 01777 nk->sec_desc->sec_desc = sec_desc; 01778 nk->sec_desc->ref_count = 0; 01779 01780 /* size value must be self-inclusive */ 01781 nk->sec_desc->size = sec_desc_size(sec_desc) + sizeof(uint32); 01782 01783 DLIST_ADD_END( file->sec_desc_list, nk->sec_desc, REGF_SK_REC *); 01784 01785 /* update the offsets for us and the previous sd in the list. 01786 if this is the first record, then just set the next and prev 01787 offsets to ourself. */ 01788 01789 if ( nk->sec_desc->prev ) { 01790 REGF_SK_REC *prev = nk->sec_desc->prev; 01791 01792 nk->sec_desc->prev_sk_off = prev->hbin_off + prev->hbin->first_hbin_off - HBIN_HDR_SIZE; 01793 prev->next_sk_off = nk->sec_desc->sk_off; 01794 01795 /* the end must loop around to the front */ 01796 nk->sec_desc->next_sk_off = file->sec_desc_list->sk_off; 01797 01798 /* and first must loop around to the tail */ 01799 file->sec_desc_list->prev_sk_off = nk->sec_desc->sk_off; 01800 } else { 01801 nk->sec_desc->prev_sk_off = nk->sec_desc->sk_off; 01802 nk->sec_desc->next_sk_off = nk->sec_desc->sk_off; 01803 } 01804 } 01805 01806 /* bump the reference count +1 */ 01807 01808 nk->sk_off = nk->sec_desc->sk_off; 01809 nk->sec_desc->ref_count++; 01810 } 01811 01812 /* write the subkeys */ 01813 01814 nk->subkeys_off = REGF_OFFSET_NONE; 01815 if ( (nk->num_subkeys = regsubkey_ctr_numkeys( subkeys )) != 0 ) { 01816 uint32 lf_size = lf_record_data_size( nk->num_subkeys ); 01817 uint32 namelen; 01818 int i; 01819 01820 if (!(nk->subkeys.hbin = find_free_space( file, lf_size ))) { 01821 return NULL; 01822 } 01823 nk->subkeys.hbin_off = prs_offset( &nk->subkeys.hbin->ps ); 01824 nk->subkeys.rec_size = (lf_size-1) ^ 0xFFFFFFFF; 01825 nk->subkeys_off = prs_offset( &nk->subkeys.hbin->ps ) + nk->subkeys.hbin->first_hbin_off - HBIN_HDR_SIZE; 01826 01827 memcpy( nk->subkeys.header, "lf", REC_HDR_SIZE ); 01828 01829 nk->subkeys.num_keys = nk->num_subkeys; 01830 if (nk->subkeys.num_keys) { 01831 if ( !(nk->subkeys.hashes = TALLOC_ZERO_ARRAY( file->mem_ctx, REGF_HASH_REC, nk->subkeys.num_keys )) ) 01832 return NULL; 01833 } else { 01834 nk->subkeys.hashes = NULL; 01835 } 01836 nk->subkey_index = 0; 01837 01838 /* update the max_bytes_subkey{name,classname} fields */ 01839 for ( i=0; i<nk->num_subkeys; i++ ) { 01840 namelen = strlen( regsubkey_ctr_specific_key(subkeys, i) ); 01841 if ( namelen*2 > nk->max_bytes_subkeyname ) 01842 nk->max_bytes_subkeyname = namelen * 2; 01843 } 01844 } 01845 01846 /* write the values */ 01847 01848 nk->values_off = REGF_OFFSET_NONE; 01849 if ( (nk->num_values = regval_ctr_numvals( values )) != 0 ) { 01850 uint32 vlist_size = ( ( nk->num_values * sizeof(uint32) ) & 0xfffffff8 ) + 8; 01851 int i; 01852 01853 if (!(vlist_hbin = find_free_space( file, vlist_size ))) { 01854 return NULL; 01855 } 01856 nk->values_off = prs_offset( &vlist_hbin->ps ) + vlist_hbin->first_hbin_off - HBIN_HDR_SIZE; 01857 01858 if (nk->num_values) { 01859 if ( !(nk->values = TALLOC_ARRAY( file->mem_ctx, REGF_VK_REC, nk->num_values )) ) 01860 return NULL; 01861 } else { 01862 nk->values = NULL; 01863 } 01864 01865 /* create the vk records */ 01866 01867 for ( i=0; i<nk->num_values; i++ ) { 01868 uint32 vk_size, namelen, datalen; 01869 REGISTRY_VALUE *r; 01870 01871 r = regval_ctr_specific_value( values, i ); 01872 create_vk_record( file, &nk->values[i], r ); 01873 vk_size = vk_record_data_size( &nk->values[i] ); 01874 nk->values[i].hbin = find_free_space( file, vk_size ); 01875 nk->values[i].hbin_off = prs_offset( &nk->values[i].hbin->ps ); 01876 nk->values[i].rec_size = ( vk_size - 1 ) ^ 0xFFFFFFFF; 01877 nk->values[i].rec_off = prs_offset( &nk->values[i].hbin->ps ) 01878 + nk->values[i].hbin->first_hbin_off 01879 - HBIN_HDR_SIZE; 01880 01881 /* update the max bytes fields if necessary */ 01882 01883 namelen = strlen( regval_name(r) ); 01884 if ( namelen*2 > nk->max_bytes_valuename ) 01885 nk->max_bytes_valuename = namelen * 2; 01886 01887 datalen = regval_size( r ); 01888 if ( datalen > nk->max_bytes_value ) 01889 nk->max_bytes_value = datalen; 01890 } 01891 } 01892 01893 /* stream the records */ 01894 01895 prs_set_offset( &nk->hbin->ps, nk->hbin_off ); 01896 if ( !prs_nk_rec( "nk_rec", &nk->hbin->ps, 0, nk ) ) 01897 return False; 01898 01899 if ( nk->num_values ) { 01900 if ( !hbin_prs_vk_records( "vk_records", vlist_hbin, 0, nk, file ) ) 01901 return False; 01902 } 01903 01904 01905 regfio_flush( file ); 01906 01907 return nk; 01908 }