static int write_block | ( | REGF_FILE * | file, | |
prs_struct * | ps, | |||
uint32 | offset | |||
) | [static] |
参照先 errno・REGF_FILE::fd・strerror()・sys_fstat().
参照元 init_regf_block()・regfio_close()・write_hbin_block().
00035 { 00036 int bytes_written, returned; 00037 char *buffer = prs_data_p( ps ); 00038 uint32 buffer_size = prs_data_size( ps ); 00039 SMB_STRUCT_STAT sbuf; 00040 00041 if ( file->fd == -1 ) 00042 return -1; 00043 00044 /* check for end of file */ 00045 00046 if ( sys_fstat( file->fd, &sbuf ) ) { 00047 DEBUG(0,("write_block: stat() failed! (%s)\n", strerror(errno))); 00048 return -1; 00049 } 00050 00051 if ( lseek( file->fd, offset, SEEK_SET ) == -1 ) { 00052 DEBUG(0,("write_block: lseek() failed! (%s)\n", strerror(errno) )); 00053 return -1; 00054 } 00055 00056 bytes_written = returned = 0; 00057 while ( bytes_written < buffer_size ) { 00058 if ( (returned = write( file->fd, buffer+bytes_written, buffer_size-bytes_written )) == -1 ) { 00059 DEBUG(0,("write_block: write() failed! (%s)\n", strerror(errno) )); 00060 return False; 00061 } 00062 00063 bytes_written += returned; 00064 } 00065 00066 return bytes_written; 00067 }
static int read_block | ( | REGF_FILE * | file, | |
prs_struct * | ps, | |||
uint32 | file_offset, | |||
uint32 | block_size | |||
) | [static] |
参照先 errno・REGF_FILE::fd・REGF_FILE::mem_ctx・prs_init()・strerror()・sys_fstat().
参照元 read_hbin_block()・read_regf_block()・regfio_close().
00073 { 00074 int bytes_read, returned; 00075 char *buffer; 00076 SMB_STRUCT_STAT sbuf; 00077 00078 /* check for end of file */ 00079 00080 if ( sys_fstat( file->fd, &sbuf ) ) { 00081 DEBUG(0,("read_block: stat() failed! (%s)\n", strerror(errno))); 00082 return -1; 00083 } 00084 00085 if ( (size_t)file_offset >= sbuf.st_size ) 00086 return -1; 00087 00088 /* if block_size == 0, we are parsing HBIN records and need 00089 to read some of the header to get the block_size from there */ 00090 00091 if ( block_size == 0 ) { 00092 char hdr[0x20]; 00093 00094 if ( lseek( file->fd, file_offset, SEEK_SET ) == -1 ) { 00095 DEBUG(0,("read_block: lseek() failed! (%s)\n", strerror(errno) )); 00096 return -1; 00097 } 00098 00099 returned = read( file->fd, hdr, 0x20 ); 00100 if ( (returned == -1) || (returned < 0x20) ) { 00101 DEBUG(0,("read_block: failed to read in HBIN header. Is the file corrupt?\n")); 00102 return -1; 00103 } 00104 00105 /* make sure this is an hbin header */ 00106 00107 if ( strncmp( hdr, "hbin", HBIN_HDR_SIZE ) != 0 ) { 00108 DEBUG(0,("read_block: invalid block header!\n")); 00109 return -1; 00110 } 00111 00112 block_size = IVAL( hdr, 0x08 ); 00113 } 00114 00115 DEBUG(10,("read_block: block_size == 0x%x\n", block_size )); 00116 00117 /* set the offset, initialize the buffer, and read the block from disk */ 00118 00119 if ( lseek( file->fd, file_offset, SEEK_SET ) == -1 ) { 00120 DEBUG(0,("read_block: lseek() failed! (%s)\n", strerror(errno) )); 00121 return -1; 00122 } 00123 00124 prs_init( ps, block_size, file->mem_ctx, UNMARSHALL ); 00125 buffer = prs_data_p( ps ); 00126 bytes_read = returned = 0; 00127 00128 while ( bytes_read < block_size ) { 00129 if ( (returned = read( file->fd, buffer+bytes_read, block_size-bytes_read )) == -1 ) { 00130 DEBUG(0,("read_block: read() failed (%s)\n", strerror(errno) )); 00131 return False; 00132 } 00133 if ( (returned == 0) && (bytes_read < block_size) ) { 00134 DEBUG(0,("read_block: not a vald registry file ?\n" )); 00135 return False; 00136 } 00137 00138 bytes_read += returned; 00139 } 00140 00141 return bytes_read; 00142 }
参照先 regf_hbin::dirty・regf_hbin::file_off・regf_hbin::free_off・regf_hbin::free_size・regf_hbin::ps・write_block().
参照元 hbin_block_close()・regf_hbin_allocate()・regfio_flush().
00148 { 00149 if ( !hbin->dirty ) 00150 return True; 00151 00152 /* write free space record if any is available */ 00153 00154 if ( hbin->free_off != REGF_OFFSET_NONE ) { 00155 uint32 header = 0xffffffff; 00156 00157 if ( !prs_set_offset( &hbin->ps, hbin->free_off-sizeof(uint32) ) ) 00158 return False; 00159 if ( !prs_uint32( "free_size", &hbin->ps, 0, &hbin->free_size ) ) 00160 return False; 00161 if ( !prs_uint32( "free_header", &hbin->ps, 0, &header ) ) 00162 return False; 00163 } 00164 00165 hbin->dirty = (write_block( file, &hbin->ps, hbin->file_off ) != -1); 00166 00167 return hbin->dirty; 00168 }
参照先 REGF_FILE::block_list・regf_hbin::next・write_hbin_block().
参照元 regfio_close().
00174 { 00175 REGF_HBIN *p; 00176 00177 /* remove the block from the open list and flush it to disk */ 00178 00179 for ( p=file->block_list; p && p!=hbin; p=p->next ) 00180 ;; 00181 00182 if ( p == hbin ) { 00183 DLIST_REMOVE( file->block_list, hbin ); 00184 } 00185 else 00186 DEBUG(0,("hbin_block_close: block not in open list!\n")); 00187 00188 if ( !write_hbin_block( file, hbin ) ) 00189 return False; 00190 00191 return True; 00192 }
static BOOL prs_regf_block | ( | const char * | desc, | |
prs_struct * | ps, | |||
int | depth, | |||
REGF_FILE * | file | |||
) | [static] |
参照先 REGF_FILE::checksum・REGF_FILE::data_offset・REGF_FILE::header・REGF_FILE::last_block・REGF_FILE::mtime・prs_debug()・smb_io_time()・REGF_FILE::unknown1・REGF_FILE::unknown2・REGF_FILE::unknown3・REGF_FILE::unknown4・REGF_FILE::unknown5・REGF_FILE::unknown6.
参照元 init_regf_block()・read_regf_block()・regfio_close().
00198 { 00199 prs_debug(ps, depth, desc, "prs_regf_block"); 00200 depth++; 00201 00202 if ( !prs_uint8s( True, "header", ps, depth, (uint8*)file->header, sizeof( file->header )) ) 00203 return False; 00204 00205 /* yes, these values are always identical so store them only once */ 00206 00207 if ( !prs_uint32( "unknown1", ps, depth, &file->unknown1 )) 00208 return False; 00209 if ( !prs_uint32( "unknown1 (again)", ps, depth, &file->unknown1 )) 00210 return False; 00211 00212 /* get the modtime */ 00213 00214 if ( !prs_set_offset( ps, 0x0c ) ) 00215 return False; 00216 if ( !smb_io_time( "modtime", &file->mtime, ps, depth ) ) 00217 return False; 00218 00219 /* constants */ 00220 00221 if ( !prs_uint32( "unknown2", ps, depth, &file->unknown2 )) 00222 return False; 00223 if ( !prs_uint32( "unknown3", ps, depth, &file->unknown3 )) 00224 return False; 00225 if ( !prs_uint32( "unknown4", ps, depth, &file->unknown4 )) 00226 return False; 00227 if ( !prs_uint32( "unknown5", ps, depth, &file->unknown5 )) 00228 return False; 00229 00230 /* get file offsets */ 00231 00232 if ( !prs_set_offset( ps, 0x24 ) ) 00233 return False; 00234 if ( !prs_uint32( "data_offset", ps, depth, &file->data_offset )) 00235 return False; 00236 if ( !prs_uint32( "last_block", ps, depth, &file->last_block )) 00237 return False; 00238 00239 /* one more constant */ 00240 00241 if ( !prs_uint32( "unknown6", ps, depth, &file->unknown6 )) 00242 return False; 00243 00244 /* get the checksum */ 00245 00246 if ( !prs_set_offset( ps, 0x01fc ) ) 00247 return False; 00248 if ( !prs_uint32( "checksum", ps, depth, &file->checksum )) 00249 return False; 00250 00251 return True; 00252 }
static BOOL prs_hbin_block | ( | const char * | desc, | |
prs_struct * | ps, | |||
int | depth, | |||
REGF_HBIN * | hbin | |||
) | [static] |
参照先 regf_hbin::block_size・regf_hbin::dirty・regf_hbin::first_hbin_off・regf_hbin::header・prs_debug().
参照元 read_hbin_block()・regf_hbin_allocate().
00258 { 00259 uint32 block_size2; 00260 00261 prs_debug(ps, depth, desc, "prs_regf_block"); 00262 depth++; 00263 00264 if ( !prs_uint8s( True, "header", ps, depth, (uint8*)hbin->header, sizeof( hbin->header )) ) 00265 return False; 00266 00267 if ( !prs_uint32( "first_hbin_off", ps, depth, &hbin->first_hbin_off )) 00268 return False; 00269 00270 /* The dosreg.cpp comments say that the block size is at 0x1c. 00271 According to a WINXP NTUSER.dat file, this is wrong. The block_size 00272 is at 0x08 */ 00273 00274 if ( !prs_uint32( "block_size", ps, depth, &hbin->block_size )) 00275 return False; 00276 00277 block_size2 = hbin->block_size; 00278 prs_set_offset( ps, 0x1c ); 00279 if ( !prs_uint32( "block_size2", ps, depth, &block_size2 )) 00280 return False; 00281 00282 if ( MARSHALLING(ps) ) 00283 hbin->dirty = True; 00284 00285 00286 return True; 00287 }
static BOOL prs_nk_rec | ( | const char * | desc, | |
prs_struct * | ps, | |||
int | depth, | |||
REGF_NK_REC * | nk | |||
) | [static] |
参照先 REGF_NK_REC::classname・REGF_NK_REC::classname_off・regf_hbin::dirty・REGF_NK_REC::hbin・REGF_NK_REC::hbin_off・REGF_NK_REC::header・REGF_NK_REC::key_type・REGF_NK_REC::keyname・REGF_NK_REC::max_bytes_subkeyclassname・REGF_NK_REC::max_bytes_subkeyname・REGF_NK_REC::max_bytes_value・REGF_NK_REC::max_bytes_valuename・REGF_NK_REC::mtime・REGF_NK_REC::num_subkeys・REGF_NK_REC::num_values・REGF_NK_REC::parent_off・prs_debug()・REGF_NK_REC::rec_size・REGF_NK_REC::sk_off・smb_io_time()・REGF_NK_REC::subkeys_off・REGF_NK_REC::unk_index・REGF_NK_REC::values_off.
参照元 hbin_prs_key()・regfio_write_key().
00293 { 00294 uint16 class_length, name_length; 00295 uint32 start; 00296 uint32 data_size, start_off, end_off; 00297 uint32 unknown_off = REGF_OFFSET_NONE; 00298 00299 nk->hbin_off = prs_offset( ps ); 00300 start = nk->hbin_off; 00301 00302 prs_debug(ps, depth, desc, "prs_nk_rec"); 00303 depth++; 00304 00305 /* back up and get the data_size */ 00306 00307 if ( !prs_set_offset( ps, prs_offset(ps)-sizeof(uint32)) ) 00308 return False; 00309 start_off = prs_offset( ps ); 00310 if ( !prs_uint32( "rec_size", ps, depth, &nk->rec_size )) 00311 return False; 00312 00313 if ( !prs_uint8s( True, "header", ps, depth, (uint8*)nk->header, sizeof( nk->header )) ) 00314 return False; 00315 00316 if ( !prs_uint16( "key_type", ps, depth, &nk->key_type )) 00317 return False; 00318 if ( !smb_io_time( "mtime", &nk->mtime, ps, depth )) 00319 return False; 00320 00321 if ( !prs_set_offset( ps, start+0x0010 ) ) 00322 return False; 00323 if ( !prs_uint32( "parent_off", ps, depth, &nk->parent_off )) 00324 return False; 00325 if ( !prs_uint32( "num_subkeys", ps, depth, &nk->num_subkeys )) 00326 return False; 00327 00328 if ( !prs_set_offset( ps, start+0x001c ) ) 00329 return False; 00330 if ( !prs_uint32( "subkeys_off", ps, depth, &nk->subkeys_off )) 00331 return False; 00332 if ( !prs_uint32( "unknown_off", ps, depth, &unknown_off) ) 00333 return False; 00334 00335 if ( !prs_set_offset( ps, start+0x0024 ) ) 00336 return False; 00337 if ( !prs_uint32( "num_values", ps, depth, &nk->num_values )) 00338 return False; 00339 if ( !prs_uint32( "values_off", ps, depth, &nk->values_off )) 00340 return False; 00341 if ( !prs_uint32( "sk_off", ps, depth, &nk->sk_off )) 00342 return False; 00343 if ( !prs_uint32( "classname_off", ps, depth, &nk->classname_off )) 00344 return False; 00345 00346 if ( !prs_uint32( "max_bytes_subkeyname", ps, depth, &nk->max_bytes_subkeyname)) 00347 return False; 00348 if ( !prs_uint32( "max_bytes_subkeyclassname", ps, depth, &nk->max_bytes_subkeyclassname)) 00349 return False; 00350 if ( !prs_uint32( "max_bytes_valuename", ps, depth, &nk->max_bytes_valuename)) 00351 return False; 00352 if ( !prs_uint32( "max_bytes_value", ps, depth, &nk->max_bytes_value)) 00353 return False; 00354 if ( !prs_uint32( "unknown index", ps, depth, &nk->unk_index)) 00355 return False; 00356 00357 name_length = nk->keyname ? strlen(nk->keyname) : 0 ; 00358 class_length = nk->classname ? strlen(nk->classname) : 0 ; 00359 if ( !prs_uint16( "name_length", ps, depth, &name_length )) 00360 return False; 00361 if ( !prs_uint16( "class_length", ps, depth, &class_length )) 00362 return False; 00363 00364 if ( class_length ) { 00365 ;; 00366 } 00367 00368 if ( name_length ) { 00369 if ( UNMARSHALLING(ps) ) { 00370 if ( !(nk->keyname = PRS_ALLOC_MEM( ps, char, name_length+1 )) ) 00371 return False; 00372 } 00373 00374 if ( !prs_uint8s( True, "name", ps, depth, (uint8*)nk->keyname, name_length) ) 00375 return False; 00376 00377 if ( UNMARSHALLING(ps) ) 00378 nk->keyname[name_length] = '\0'; 00379 } 00380 00381 end_off = prs_offset( ps ); 00382 00383 /* data_size must be divisible by 8 and large enough to hold the original record */ 00384 00385 data_size = ((start_off - end_off) & 0xfffffff8 ); 00386 if ( data_size > nk->rec_size ) 00387 DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, nk->rec_size)); 00388 00389 if ( MARSHALLING(ps) ) 00390 nk->hbin->dirty = True; 00391 00392 return True; 00393 }
static uint32 regf_block_checksum | ( | prs_struct * | ps | ) | [static] |
参照元 init_regf_block()・read_regf_block()・regfio_close().
00399 { 00400 char *buffer = prs_data_p( ps ); 00401 uint32 checksum, x; 00402 int i; 00403 00404 /* XOR of all bytes 0x0000 - 0x01FB */ 00405 00406 checksum = x = 0; 00407 00408 for ( i=0; i<0x01FB; i+=4 ) { 00409 x = IVAL(buffer, i ); 00410 checksum ^= x; 00411 } 00412 00413 return checksum; 00414 }
参照先 REGF_FILE::checksum・prs_mem_free()・prs_regf_block()・read_block()・regf_block_checksum().
参照元 regfio_open().
00420 { 00421 prs_struct ps; 00422 uint32 checksum; 00423 00424 /* grab the first block from the file */ 00425 00426 if ( read_block( file, &ps, 0, REGF_BLOCKSIZE ) == -1 ) 00427 return False; 00428 00429 /* parse the block and verify the checksum */ 00430 00431 if ( !prs_regf_block( "regf_header", &ps, 0, file ) ) 00432 return False; 00433 00434 checksum = regf_block_checksum( &ps ); 00435 00436 prs_mem_free( &ps ); 00437 00438 if ( file->checksum != checksum ) { 00439 DEBUG(0,("read_regf_block: invalid checksum\n" )); 00440 return False; 00441 } 00442 00443 return True; 00444 }
参照先 REGF_FILE::data_offset・regf_hbin::file_off・regf_hbin::free_off・regf_hbin::free_size・REGF_FILE::mem_ctx・prs_hbin_block()・regf_hbin::ps・read_block().
参照元 find_free_space()・lookup_hbin_block()・regfio_rootkey().
00450 { 00451 REGF_HBIN *hbin; 00452 uint32 record_size, curr_off, block_size, header; 00453 00454 if ( !(hbin = TALLOC_ZERO_P(file->mem_ctx, REGF_HBIN)) ) 00455 return NULL; 00456 hbin->file_off = offset; 00457 hbin->free_off = -1; 00458 00459 if ( read_block( file, &hbin->ps, offset, 0 ) == -1 ) 00460 return NULL; 00461 00462 if ( !prs_hbin_block( "hbin", &hbin->ps, 0, hbin ) ) 00463 return NULL; 00464 00465 /* this should be the same thing as hbin->block_size but just in case */ 00466 00467 block_size = prs_data_size( &hbin->ps ); 00468 00469 /* Find the available free space offset. Always at the end, 00470 so walk the record list and stop when you get to the end. 00471 The end is defined by a record header of 0xffffffff. The 00472 previous 4 bytes contains the amount of free space remaining 00473 in the hbin block. */ 00474 00475 /* remember that the record_size is in the 4 bytes preceeding the record itself */ 00476 00477 if ( !prs_set_offset( &hbin->ps, file->data_offset+HBIN_HDR_SIZE-sizeof(uint32) ) ) 00478 return False; 00479 00480 record_size = 0; 00481 header = 0; 00482 curr_off = prs_offset( &hbin->ps ); 00483 while ( header != 0xffffffff ) { 00484 /* not done yet so reset the current offset to the 00485 next record_size field */ 00486 00487 curr_off = curr_off+record_size; 00488 00489 /* for some reason the record_size of the last record in 00490 an hbin block can extend past the end of the block 00491 even though the record fits within the remaining 00492 space....aaarrrgggghhhhhh */ 00493 00494 if ( curr_off >= block_size ) { 00495 record_size = -1; 00496 curr_off = -1; 00497 break; 00498 } 00499 00500 if ( !prs_set_offset( &hbin->ps, curr_off) ) 00501 return False; 00502 00503 if ( !prs_uint32( "rec_size", &hbin->ps, 0, &record_size ) ) 00504 return False; 00505 if ( !prs_uint32( "header", &hbin->ps, 0, &header ) ) 00506 return False; 00507 00508 SMB_ASSERT( record_size != 0 ); 00509 00510 if ( record_size & 0x80000000 ) { 00511 /* absolute_value(record_size) */ 00512 record_size = (record_size ^ 0xffffffff) + 1; 00513 } 00514 } 00515 00516 /* save the free space offset */ 00517 00518 if ( header == 0xffffffff ) { 00519 00520 /* account for the fact that the curr_off is 4 bytes behind the actual 00521 record header */ 00522 00523 hbin->free_off = curr_off + sizeof(uint32); 00524 hbin->free_size = record_size; 00525 } 00526 00527 DEBUG(10,("read_hbin_block: free space offset == 0x%x\n", hbin->free_off)); 00528 00529 if ( !prs_set_offset( &hbin->ps, file->data_offset+HBIN_HDR_SIZE ) ) 00530 return False; 00531 00532 return hbin; 00533 }
参照先 regf_hbin::block_size・regf_hbin::first_hbin_off.
参照元 hbin_prs_key()・hbin_prs_vk_rec()・hbin_prs_vk_records()・lookup_hbin_block().
00541 { 00542 if ( !hbin ) 00543 return False; 00544 00545 if ( (offset > hbin->first_hbin_off) && (offset < (hbin->first_hbin_off+hbin->block_size)) ) 00546 return True; 00547 00548 return False; 00549 }
参照先 REGF_FILE::block_list・regf_hbin::block_size・regf_hbin::file_off・hbin_contains_offset()・regf_hbin::next・prs_mem_free()・regf_hbin::ps・read_hbin_block().
参照元 hbin_prs_key()・hbin_prs_vk_rec()・hbin_prs_vk_records()・regfio_fetch_subkey().
00557 { 00558 REGF_HBIN *hbin = NULL; 00559 uint32 block_off; 00560 00561 /* start with the open list */ 00562 00563 for ( hbin=file->block_list; hbin; hbin=hbin->next ) { 00564 DEBUG(10,("lookup_hbin_block: address = 0x%x [0x%lx]\n", hbin->file_off, (unsigned long)hbin )); 00565 if ( hbin_contains_offset( hbin, offset ) ) 00566 return hbin; 00567 } 00568 00569 if ( !hbin ) { 00570 /* start at the beginning */ 00571 00572 block_off = REGF_BLOCKSIZE; 00573 do { 00574 /* cleanup before the next round */ 00575 if ( hbin ) 00576 prs_mem_free( &hbin->ps ); 00577 00578 hbin = read_hbin_block( file, block_off ); 00579 00580 if ( hbin ) 00581 block_off = hbin->file_off + hbin->block_size; 00582 00583 } while ( hbin && !hbin_contains_offset( hbin, offset ) ); 00584 } 00585 00586 if ( hbin ) 00587 DLIST_ADD( file->block_list, hbin ); 00588 00589 return hbin; 00590 }
static BOOL prs_hash_rec | ( | const char * | desc, | |
prs_struct * | ps, | |||
int | depth, | |||
REGF_HASH_REC * | hash | |||
) | [static] |
参照先 REGF_HASH_REC::keycheck・REGF_HASH_REC::nk_off・prs_debug().
00596 { 00597 prs_debug(ps, depth, desc, "prs_hash_rec"); 00598 depth++; 00599 00600 if ( !prs_uint32( "nk_off", ps, depth, &hash->nk_off )) 00601 return False; 00602 if ( !prs_uint8s( True, "keycheck", ps, depth, hash->keycheck, sizeof( hash->keycheck )) ) 00603 return False; 00604 00605 return True; 00606 }
static BOOL hbin_prs_lf_records | ( | const char * | desc, | |
REGF_HBIN * | hbin, | |||
int | depth, | |||
REGF_NK_REC * | nk | |||
) | [static] |
参照先 regf_hbin::dirty・regf_hbin::first_hbin_off・REGF_LF_REC::hashes・REGF_LF_REC::header・REGF_LF_REC::num_keys・REGF_NK_REC::num_subkeys・prs_debug()・prs_hash_rec()・regf_hbin::ps・REGF_LF_REC::rec_size・REGF_NK_REC::subkeys・REGF_NK_REC::subkeys_off.
参照元 hbin_prs_key()・regfio_write_key().
00612 { 00613 int i; 00614 REGF_LF_REC *lf = &nk->subkeys; 00615 uint32 data_size, start_off, end_off; 00616 00617 prs_debug(&hbin->ps, depth, desc, "prs_lf_records"); 00618 depth++; 00619 00620 /* check if we have anything to do first */ 00621 00622 if ( nk->num_subkeys == 0 ) 00623 return True; 00624 00625 /* move to the LF record */ 00626 00627 if ( !prs_set_offset( &hbin->ps, nk->subkeys_off + HBIN_HDR_SIZE - hbin->first_hbin_off ) ) 00628 return False; 00629 00630 /* backup and get the data_size */ 00631 00632 if ( !prs_set_offset( &hbin->ps, prs_offset(&hbin->ps)-sizeof(uint32)) ) 00633 return False; 00634 start_off = prs_offset( &hbin->ps ); 00635 if ( !prs_uint32( "rec_size", &hbin->ps, depth, &lf->rec_size )) 00636 return False; 00637 00638 if ( !prs_uint8s( True, "header", &hbin->ps, depth, (uint8*)lf->header, sizeof( lf->header )) ) 00639 return False; 00640 00641 if ( !prs_uint16( "num_keys", &hbin->ps, depth, &lf->num_keys)) 00642 return False; 00643 00644 if ( UNMARSHALLING(&hbin->ps) ) { 00645 if (lf->num_keys) { 00646 if ( !(lf->hashes = PRS_ALLOC_MEM( &hbin->ps, REGF_HASH_REC, lf->num_keys )) ) 00647 return False; 00648 } else { 00649 lf->hashes = NULL; 00650 } 00651 } 00652 00653 for ( i=0; i<lf->num_keys; i++ ) { 00654 if ( !prs_hash_rec( "hash_rec", &hbin->ps, depth, &lf->hashes[i] ) ) 00655 return False; 00656 } 00657 00658 end_off = prs_offset( &hbin->ps ); 00659 00660 /* data_size must be divisible by 8 and large enough to hold the original record */ 00661 00662 data_size = ((start_off - end_off) & 0xfffffff8 ); 00663 if ( data_size > lf->rec_size ) 00664 DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->rec_size)); 00665 00666 if ( MARSHALLING(&hbin->ps) ) 00667 hbin->dirty = True; 00668 00669 return True; 00670 }
static BOOL hbin_prs_sk_rec | ( | const char * | desc, | |
REGF_HBIN * | hbin, | |||
int | depth, | |||
REGF_SK_REC * | sk | |||
) | [static] |
参照先 regf_hbin::dirty・regf_hbin::first_hbin_off・_regf_sk_rec::header・_regf_sk_rec::next_sk_off・_regf_sk_rec::prev_sk_off・prs_debug()・regf_hbin::ps・_regf_sk_rec::rec_size・_regf_sk_rec::ref_count・_regf_sk_rec::sec_desc・sec_io_desc()・_regf_sk_rec::size・_regf_sk_rec::sk_off.
参照元 hbin_prs_key()・regfio_close().
00676 { 00677 prs_struct *ps = &hbin->ps; 00678 uint16 tag = 0xFFFF; 00679 uint32 data_size, start_off, end_off; 00680 00681 00682 prs_debug(ps, depth, desc, "hbin_prs_sk_rec"); 00683 depth++; 00684 00685 if ( !prs_set_offset( &hbin->ps, sk->sk_off + HBIN_HDR_SIZE - hbin->first_hbin_off ) ) 00686 return False; 00687 00688 /* backup and get the data_size */ 00689 00690 if ( !prs_set_offset( &hbin->ps, prs_offset(&hbin->ps)-sizeof(uint32)) ) 00691 return False; 00692 start_off = prs_offset( &hbin->ps ); 00693 if ( !prs_uint32( "rec_size", &hbin->ps, depth, &sk->rec_size )) 00694 return False; 00695 00696 if ( !prs_uint8s( True, "header", ps, depth, (uint8*)sk->header, sizeof( sk->header )) ) 00697 return False; 00698 if ( !prs_uint16( "tag", ps, depth, &tag)) 00699 return False; 00700 00701 if ( !prs_uint32( "prev_sk_off", ps, depth, &sk->prev_sk_off)) 00702 return False; 00703 if ( !prs_uint32( "next_sk_off", ps, depth, &sk->next_sk_off)) 00704 return False; 00705 if ( !prs_uint32( "ref_count", ps, depth, &sk->ref_count)) 00706 return False; 00707 if ( !prs_uint32( "size", ps, depth, &sk->size)) 00708 return False; 00709 00710 if ( !sec_io_desc( "sec_desc", &sk->sec_desc, ps, depth )) 00711 return False; 00712 00713 end_off = prs_offset( &hbin->ps ); 00714 00715 /* data_size must be divisible by 8 and large enough to hold the original record */ 00716 00717 data_size = ((start_off - end_off) & 0xfffffff8 ); 00718 if ( data_size > sk->rec_size ) 00719 DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->rec_size)); 00720 00721 if ( MARSHALLING(&hbin->ps) ) 00722 hbin->dirty = True; 00723 00724 return True; 00725 }
static BOOL hbin_prs_vk_rec | ( | const char * | desc, | |
REGF_HBIN * | hbin, | |||
int | depth, | |||
REGF_VK_REC * | vk, | |||
REGF_FILE * | file | |||
) | [static] |
参照先 REGF_VK_REC::data・REGF_VK_REC::data_off・REGF_VK_REC::data_size・regf_hbin::dirty・regf_hbin::first_hbin_off・REGF_VK_REC::flag・hbin_contains_offset()・REGF_VK_REC::header・lookup_hbin_block()・prs_debug()・regf_hbin::ps・REGF_VK_REC::rec_size・REGF_VK_REC::type・REGF_VK_REC::valuename.
00731 { 00732 uint32 offset; 00733 uint16 name_length; 00734 prs_struct *ps = &hbin->ps; 00735 uint32 data_size, start_off, end_off; 00736 00737 prs_debug(ps, depth, desc, "prs_vk_rec"); 00738 depth++; 00739 00740 /* backup and get the data_size */ 00741 00742 if ( !prs_set_offset( &hbin->ps, prs_offset(&hbin->ps)-sizeof(uint32)) ) 00743 return False; 00744 start_off = prs_offset( &hbin->ps ); 00745 if ( !prs_uint32( "rec_size", &hbin->ps, depth, &vk->rec_size )) 00746 return False; 00747 00748 if ( !prs_uint8s( True, "header", ps, depth, (uint8*)vk->header, sizeof( vk->header )) ) 00749 return False; 00750 00751 if ( MARSHALLING(&hbin->ps) ) 00752 name_length = strlen(vk->valuename); 00753 00754 if ( !prs_uint16( "name_length", ps, depth, &name_length )) 00755 return False; 00756 if ( !prs_uint32( "data_size", ps, depth, &vk->data_size )) 00757 return False; 00758 if ( !prs_uint32( "data_off", ps, depth, &vk->data_off )) 00759 return False; 00760 if ( !prs_uint32( "type", ps, depth, &vk->type)) 00761 return False; 00762 if ( !prs_uint16( "flag", ps, depth, &vk->flag)) 00763 return False; 00764 00765 offset = prs_offset( ps ); 00766 offset += 2; /* skip 2 bytes */ 00767 prs_set_offset( ps, offset ); 00768 00769 /* get the name */ 00770 00771 if ( vk->flag&VK_FLAG_NAME_PRESENT ) { 00772 00773 if ( UNMARSHALLING(&hbin->ps) ) { 00774 if ( !(vk->valuename = PRS_ALLOC_MEM( ps, char, name_length+1 ))) 00775 return False; 00776 } 00777 if ( !prs_uint8s( True, "name", ps, depth, (uint8*)vk->valuename, name_length ) ) 00778 return False; 00779 } 00780 00781 end_off = prs_offset( &hbin->ps ); 00782 00783 /* get the data if necessary */ 00784 00785 if ( vk->data_size != 0 ) { 00786 BOOL charmode = False; 00787 00788 if ( (vk->type == REG_SZ) || (vk->type == REG_MULTI_SZ) ) 00789 charmode = True; 00790 00791 /* the data is stored in the offset if the size <= 4 */ 00792 00793 if ( !(vk->data_size & VK_DATA_IN_OFFSET) ) { 00794 REGF_HBIN *hblock = hbin; 00795 uint32 data_rec_size; 00796 00797 if ( UNMARSHALLING(&hbin->ps) ) { 00798 if ( !(vk->data = PRS_ALLOC_MEM( ps, uint8, vk->data_size) ) ) 00799 return False; 00800 } 00801 00802 /* this data can be in another hbin */ 00803 if ( !hbin_contains_offset( hbin, vk->data_off ) ) { 00804 if ( !(hblock = lookup_hbin_block( file, vk->data_off )) ) 00805 return False; 00806 } 00807 if ( !(prs_set_offset( &hblock->ps, (vk->data_off+HBIN_HDR_SIZE-hblock->first_hbin_off)-sizeof(uint32) )) ) 00808 return False; 00809 00810 if ( MARSHALLING(&hblock->ps) ) { 00811 data_rec_size = ( (vk->data_size+sizeof(uint32)) & 0xfffffff8 ) + 8; 00812 data_rec_size = ( data_rec_size - 1 ) ^ 0xFFFFFFFF; 00813 } 00814 if ( !prs_uint32( "data_rec_size", &hblock->ps, depth, &data_rec_size )) 00815 return False; 00816 if ( !prs_uint8s( charmode, "data", &hblock->ps, depth, vk->data, vk->data_size) ) 00817 return False; 00818 00819 if ( MARSHALLING(&hblock->ps) ) 00820 hblock->dirty = True; 00821 } 00822 else { 00823 if ( !(vk->data = PRS_ALLOC_MEM( ps, uint8, 4 ) ) ) 00824 return False; 00825 SIVAL( vk->data, 0, vk->data_off ); 00826 } 00827 00828 } 00829 00830 /* data_size must be divisible by 8 and large enough to hold the original record */ 00831 00832 data_size = ((start_off - end_off ) & 0xfffffff8 ); 00833 if ( data_size != vk->rec_size ) 00834 DEBUG(10,("prs_vk_rec: data_size check failed (0x%x < 0x%x)\n", data_size, vk->rec_size)); 00835 00836 if ( MARSHALLING(&hbin->ps) ) 00837 hbin->dirty = True; 00838 00839 return True; 00840 }
static BOOL hbin_prs_vk_records | ( | const char * | desc, | |
REGF_HBIN * | hbin, | |||
int | depth, | |||
REGF_NK_REC * | nk, | |||
REGF_FILE * | file | |||
) | [static] |
参照先 regf_hbin::first_hbin_off・hbin_contains_offset()・REGF_VK_REC::hbin_off・hbin_prs_vk_rec()・lookup_hbin_block()・REGF_NK_REC::num_values・prs_debug()・regf_hbin::ps・REGF_VK_REC::rec_off・REGF_NK_REC::values・REGF_NK_REC::values_off.
参照元 hbin_prs_key()・regfio_write_key().
00848 { 00849 int i; 00850 uint32 record_size; 00851 00852 prs_debug(&hbin->ps, depth, desc, "prs_vk_records"); 00853 depth++; 00854 00855 /* check if we have anything to do first */ 00856 00857 if ( nk->num_values == 0 ) 00858 return True; 00859 00860 if ( UNMARSHALLING(&hbin->ps) ) { 00861 if ( !(nk->values = PRS_ALLOC_MEM( &hbin->ps, REGF_VK_REC, nk->num_values ) ) ) 00862 return False; 00863 } 00864 00865 /* convert the offset to something relative to this HBIN block */ 00866 00867 if ( !prs_set_offset( &hbin->ps, nk->values_off+HBIN_HDR_SIZE-hbin->first_hbin_off-sizeof(uint32)) ) 00868 return False; 00869 00870 if ( MARSHALLING( &hbin->ps) ) { 00871 record_size = ( ( nk->num_values * sizeof(uint32) ) & 0xfffffff8 ) + 8; 00872 record_size = (record_size - 1) ^ 0xFFFFFFFF; 00873 } 00874 00875 if ( !prs_uint32( "record_size", &hbin->ps, depth, &record_size ) ) 00876 return False; 00877 00878 for ( i=0; i<nk->num_values; i++ ) { 00879 if ( !prs_uint32( "vk_off", &hbin->ps, depth, &nk->values[i].rec_off ) ) 00880 return False; 00881 } 00882 00883 for ( i=0; i<nk->num_values; i++ ) { 00884 REGF_HBIN *sub_hbin = hbin; 00885 uint32 new_offset; 00886 00887 if ( !hbin_contains_offset( hbin, nk->values[i].rec_off ) ) { 00888 sub_hbin = lookup_hbin_block( file, nk->values[i].rec_off ); 00889 if ( !sub_hbin ) { 00890 DEBUG(0,("hbin_prs_vk_records: Failed to find HBIN block containing offset [0x%x]\n", 00891 nk->values[i].hbin_off)); 00892 return False; 00893 } 00894 } 00895 00896 new_offset = nk->values[i].rec_off + HBIN_HDR_SIZE - sub_hbin->first_hbin_off; 00897 if ( !prs_set_offset( &sub_hbin->ps, new_offset ) ) 00898 return False; 00899 if ( !hbin_prs_vk_rec( "vk_rec", sub_hbin, depth, &nk->values[i], file ) ) 00900 return False; 00901 } 00902 00903 if ( MARSHALLING(&hbin->ps) ) 00904 hbin->dirty = True; 00905 00906 00907 return True; 00908 }
static REGF_SK_REC* find_sk_record_by_offset | ( | REGF_FILE * | file, | |
uint32 | offset | |||
) | [static] |
参照先 _regf_sk_rec::next・REGF_FILE::sec_desc_list・_regf_sk_rec::sk_off.
参照元 hbin_prs_key().
00915 { 00916 REGF_SK_REC *p_sk; 00917 00918 for ( p_sk=file->sec_desc_list; p_sk; p_sk=p_sk->next ) { 00919 if ( p_sk->sk_off == offset ) 00920 return p_sk; 00921 } 00922 00923 return NULL; 00924 }
static REGF_SK_REC* find_sk_record_by_sec_desc | ( | REGF_FILE * | file, | |
SEC_DESC * | sd | |||
) | [static] |
参照先 _regf_sk_rec::next・_regf_sk_rec::sec_desc・sec_desc_equal()・REGF_FILE::sec_desc_list.
参照元 regfio_write_key().
00930 { 00931 REGF_SK_REC *p; 00932 00933 for ( p=file->sec_desc_list; p; p=p->next ) { 00934 if ( sec_desc_equal( p->sec_desc, sd ) ) 00935 return p; 00936 } 00937 00938 /* failure */ 00939 00940 return NULL; 00941 }
static BOOL hbin_prs_key | ( | REGF_FILE * | file, | |
REGF_HBIN * | hbin, | |||
REGF_NK_REC * | nk | |||
) | [static] |
参照先 find_sk_record_by_offset()・hbin_contains_offset()・hbin_prs_lf_records()・hbin_prs_sk_rec()・hbin_prs_vk_records()・lookup_hbin_block()・REGF_FILE::mem_ctx・REGF_NK_REC::num_subkeys・REGF_NK_REC::num_values・prs_debug()・prs_nk_rec()・regf_hbin::ps・REGF_NK_REC::sec_desc・REGF_FILE::sec_desc_list・_regf_sk_rec::sk_off・REGF_NK_REC::sk_off・REGF_NK_REC::subkeys_off・REGF_NK_REC::values_off.
参照元 next_nk_record()・regfio_fetch_subkey().
00947 { 00948 int depth = 0; 00949 REGF_HBIN *sub_hbin; 00950 00951 prs_debug(&hbin->ps, depth, "", "fetch_key"); 00952 depth++; 00953 00954 /* get the initial nk record */ 00955 00956 if ( !prs_nk_rec( "nk_rec", &hbin->ps, depth, nk )) 00957 return False; 00958 00959 /* fill in values */ 00960 00961 if ( nk->num_values && (nk->values_off!=REGF_OFFSET_NONE) ) { 00962 sub_hbin = hbin; 00963 if ( !hbin_contains_offset( hbin, nk->values_off ) ) { 00964 sub_hbin = lookup_hbin_block( file, nk->values_off ); 00965 if ( !sub_hbin ) { 00966 DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing value_list_offset [0x%x]\n", 00967 nk->values_off)); 00968 return False; 00969 } 00970 } 00971 00972 if ( !hbin_prs_vk_records( "vk_rec", sub_hbin, depth, nk, file )) 00973 return False; 00974 } 00975 00976 /* now get subkeys */ 00977 00978 if ( nk->num_subkeys && (nk->subkeys_off!=REGF_OFFSET_NONE) ) { 00979 sub_hbin = hbin; 00980 if ( !hbin_contains_offset( hbin, nk->subkeys_off ) ) { 00981 sub_hbin = lookup_hbin_block( file, nk->subkeys_off ); 00982 if ( !sub_hbin ) { 00983 DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing subkey_offset [0x%x]\n", 00984 nk->subkeys_off)); 00985 return False; 00986 } 00987 } 00988 00989 if ( !hbin_prs_lf_records( "lf_rec", sub_hbin, depth, nk )) 00990 return False; 00991 } 00992 00993 /* get the to the security descriptor. First look if we have already parsed it */ 00994 00995 if ( (nk->sk_off!=REGF_OFFSET_NONE) && !( nk->sec_desc = find_sk_record_by_offset( file, nk->sk_off )) ) { 00996 00997 sub_hbin = hbin; 00998 if ( !hbin_contains_offset( hbin, nk->sk_off ) ) { 00999 sub_hbin = lookup_hbin_block( file, nk->sk_off ); 01000 if ( !sub_hbin ) { 01001 DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing sk_offset [0x%x]\n", 01002 nk->subkeys_off)); 01003 return False; 01004 } 01005 } 01006 01007 if ( !(nk->sec_desc = TALLOC_ZERO_P( file->mem_ctx, REGF_SK_REC )) ) 01008 return False; 01009 nk->sec_desc->sk_off = nk->sk_off; 01010 if ( !hbin_prs_sk_rec( "sk_rec", sub_hbin, depth, nk->sec_desc )) 01011 return False; 01012 01013 /* add to the list of security descriptors (ref_count has been read from the files) */ 01014 01015 nk->sec_desc->sk_off = nk->sk_off; 01016 DLIST_ADD( file->sec_desc_list, nk->sec_desc ); 01017 } 01018 01019 return True; 01020 }
参照先 regf_hbin::ps.
参照元 do_command()・get_num_records_hook()・next_nk_record()・write_eventlog_tdb().
01026 { 01027 uint8 header[REC_HDR_SIZE]; 01028 uint32 record_size; 01029 uint32 curr_off, block_size; 01030 BOOL found = False; 01031 prs_struct *ps = &hbin->ps; 01032 01033 curr_off = prs_offset( ps ); 01034 if ( curr_off == 0 ) 01035 prs_set_offset( ps, HBIN_HEADER_REC_SIZE ); 01036 01037 /* assume that the current offset is at the record header 01038 and we need to backup to read the record size */ 01039 01040 curr_off -= sizeof(uint32); 01041 01042 block_size = prs_data_size( ps ); 01043 record_size = 0; 01044 memset( header, 0x0, sizeof(uint8)*REC_HDR_SIZE ); 01045 while ( !found ) { 01046 01047 curr_off = curr_off+record_size; 01048 if ( curr_off >= block_size ) 01049 break; 01050 01051 if ( !prs_set_offset( &hbin->ps, curr_off) ) 01052 return False; 01053 01054 if ( !prs_uint32( "record_size", ps, 0, &record_size ) ) 01055 return False; 01056 if ( !prs_uint8s( True, "header", ps, 0, header, REC_HDR_SIZE ) ) 01057 return False; 01058 01059 if ( record_size & 0x80000000 ) { 01060 /* absolute_value(record_size) */ 01061 record_size = (record_size ^ 0xffffffff) + 1; 01062 } 01063 01064 if ( memcmp( header, hdr, REC_HDR_SIZE ) == 0 ) { 01065 found = True; 01066 curr_off += sizeof(uint32); 01067 } 01068 } 01069 01070 /* mark prs_struct as done ( at end ) if no more SK records */ 01071 /* mark end-of-block as True */ 01072 01073 if ( !found ) { 01074 prs_set_offset( &hbin->ps, prs_data_size(&hbin->ps) ); 01075 *eob = True; 01076 return False; 01077 } 01078 01079 if ( !prs_set_offset( ps, curr_off ) ) 01080 return False; 01081 01082 return True; 01083 }
static BOOL next_nk_record | ( | REGF_FILE * | file, | |
REGF_HBIN * | hbin, | |||
REGF_NK_REC * | nk, | |||
BOOL * | eob | |||
) | [static] |
参照先 hbin_prs_key()・next_record().
参照元 regfio_rootkey().
01089 { 01090 if ( next_record( hbin, "nk", eob ) && hbin_prs_key( file, hbin, nk ) ) 01091 return True; 01092 01093 return False; 01094 }
参照先 REGF_FILE::checksum・REGF_FILE::data_offset・REGF_FILE::header・REGF_FILE::last_block・REGF_FILE::mem_ctx・REGF_FILE::mtime・prs_init()・prs_mem_free()・prs_regf_block()・regf_block_checksum()・result・unix_to_nt_time()・REGF_FILE::unknown1・REGF_FILE::unknown2・REGF_FILE::unknown3・REGF_FILE::unknown4・REGF_FILE::unknown5・REGF_FILE::unknown6・write_block().
参照元 regfio_open().
01102 { 01103 prs_struct ps; 01104 BOOL result = True; 01105 01106 if ( !prs_init( &ps, REGF_BLOCKSIZE, file->mem_ctx, MARSHALL ) ) 01107 return False; 01108 01109 memcpy( file->header, "regf", REGF_HDR_SIZE ); 01110 file->data_offset = 0x20; 01111 file->last_block = 0x1000; 01112 01113 /* set mod time */ 01114 01115 unix_to_nt_time( &file->mtime, time(NULL) ); 01116 01117 /* hard coded values...no diea what these are ... maybe in time */ 01118 01119 file->unknown1 = 0x2; 01120 file->unknown2 = 0x1; 01121 file->unknown3 = 0x3; 01122 file->unknown4 = 0x0; 01123 file->unknown5 = 0x1; 01124 file->unknown6 = 0x1; 01125 01126 /* write header to the buffer */ 01127 01128 if ( !prs_regf_block( "regf_header", &ps, 0, file ) ) { 01129 result = False; 01130 goto out; 01131 } 01132 01133 /* calculate the checksum, re-marshall data (to include the checksum) 01134 and write to disk */ 01135 01136 file->checksum = regf_block_checksum( &ps ); 01137 prs_set_offset( &ps, 0 ); 01138 if ( !prs_regf_block( "regf_header", &ps, 0, file ) ) { 01139 result = False; 01140 goto out; 01141 } 01142 01143 if ( write_block( file, &ps, 0 ) == -1 ) { 01144 DEBUG(0,("init_regf_block: Failed to initialize registry header block!\n")); 01145 result = False; 01146 goto out; 01147 } 01148 01149 out: 01150 prs_mem_free( &ps ); 01151 01152 return result; 01153 }
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 }
static void regfio_mem_free | ( | REGF_FILE * | file | ) | [static] |
参照先 REGF_FILE::mem_ctx.
参照元 regfio_close().
01215 { 01216 /* free any talloc()'d memory */ 01217 01218 if ( file && file->mem_ctx ) 01219 talloc_destroy( file->mem_ctx ); 01220 }
int regfio_close | ( | REGF_FILE * | file | ) |
参照先 REGF_FILE::block_list・REGF_FILE::checksum・REGF_FILE::fd・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 }
static void regfio_flush | ( | REGF_FILE * | file | ) | [static] |
参照先 REGF_FILE::block_list・regf_hbin::next・write_hbin_block().
参照元 regfio_write_key().
01289 { 01290 REGF_HBIN *hbin; 01291 01292 for ( hbin=file->block_list; hbin; hbin=hbin->next ) { 01293 write_hbin_block( file, hbin ); 01294 } 01295 }
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_hbin::block_size・errno・REGF_FILE::fd・regf_hbin::file_off・regf_hbin::first_hbin_off・regf_hbin::free_off・regf_hbin::free_size・regf_hbin::header・REGF_FILE::last_block・REGF_FILE::mem_ctx・prs_hbin_block()・prs_init()・regf_hbin::ps・strerror()・sys_fstat()・write_hbin_block().
参照元 find_free_space().
01395 { 01396 REGF_HBIN *hbin; 01397 SMB_STRUCT_STAT sbuf; 01398 01399 if ( !(hbin = TALLOC_ZERO_P( file->mem_ctx, REGF_HBIN )) ) 01400 return NULL; 01401 01402 memcpy( hbin->header, "hbin", sizeof(HBIN_HDR_SIZE) ); 01403 01404 01405 if ( sys_fstat( file->fd, &sbuf ) ) { 01406 DEBUG(0,("regf_hbin_allocate: stat() failed! (%s)\n", strerror(errno))); 01407 return NULL; 01408 } 01409 01410 hbin->file_off = sbuf.st_size; 01411 01412 hbin->free_off = HBIN_HEADER_REC_SIZE; 01413 hbin->free_size = block_size - hbin->free_off + sizeof(uint32);; 01414 01415 hbin->block_size = block_size; 01416 hbin->first_hbin_off = hbin->file_off - REGF_BLOCKSIZE; 01417 01418 if ( !prs_init( &hbin->ps, block_size, file->mem_ctx, MARSHALL ) ) 01419 return NULL; 01420 01421 if ( !prs_hbin_block( "new_hbin", &hbin->ps, 0, hbin ) ) 01422 return NULL; 01423 01424 if ( !write_hbin_block( file, hbin ) ) 01425 return NULL; 01426 01427 file->last_block = hbin->file_off; 01428 01429 return hbin; 01430 }
static void update_free_space | ( | REGF_HBIN * | hbin, | |
uint32 | size_used | |||
) | [static] |
参照先 regf_hbin::block_size・regf_hbin::free_off・regf_hbin::free_size.
参照元 find_free_space().
01436 { 01437 hbin->free_off += size_used; 01438 hbin->free_size -= size_used; 01439 01440 if ( hbin->free_off >= hbin->block_size ) { 01441 hbin->free_off = REGF_OFFSET_NONE; 01442 } 01443 01444 return; 01445 }
参照先 REGF_FILE::block_list・regf_hbin::block_size・regf_hbin::file_off・regf_hbin::free_off・regf_hbin::free_size・regf_hbin::next・prs_mem_free()・regf_hbin::ps・read_hbin_block()・regf_hbin_allocate()・update_free_space().
参照元 create_vk_record()・regfio_write_key().
01451 { 01452 REGF_HBIN *hbin, *p_hbin; 01453 uint32 block_off; 01454 BOOL cached; 01455 01456 /* check open block list */ 01457 01458 for ( hbin=file->block_list; hbin!=NULL; hbin=hbin->next ) { 01459 /* only check blocks that actually have available space */ 01460 01461 if ( hbin->free_off == REGF_OFFSET_NONE ) 01462 continue; 01463 01464 /* check for a large enough available chunk */ 01465 01466 if ( (hbin->block_size - hbin->free_off) >= size ) { 01467 DLIST_PROMOTE( file->block_list, hbin ); 01468 goto done; 01469 } 01470 } 01471 01472 /* parse the file until we find a block with 01473 enough free space; save the last non-filled hbin */ 01474 01475 block_off = REGF_BLOCKSIZE; 01476 do { 01477 /* cleanup before the next round */ 01478 cached = False; 01479 if ( hbin ) 01480 prs_mem_free( &hbin->ps ); 01481 01482 hbin = read_hbin_block( file, block_off ); 01483 01484 if ( hbin ) { 01485 01486 /* make sure that we don't already have this block in memory */ 01487 01488 for ( p_hbin=file->block_list; p_hbin!=NULL; p_hbin=p_hbin->next ) { 01489 if ( p_hbin->file_off == hbin->file_off ) { 01490 cached = True; 01491 break; 01492 } 01493 } 01494 01495 block_off = hbin->file_off + hbin->block_size; 01496 01497 if ( cached ) { 01498 prs_mem_free( &hbin->ps ); 01499 hbin = NULL; 01500 continue; 01501 } 01502 } 01503 /* if (cached block or (new block and not enough free space)) then continue looping */ 01504 } while ( cached || (hbin && (hbin->free_size < size)) ); 01505 01506 /* no free space; allocate a new one */ 01507 01508 if ( !hbin ) { 01509 uint32 alloc_size; 01510 01511 /* allocate in multiples of REGF_ALLOC_BLOCK; make sure (size + hbin_header) fits */ 01512 01513 alloc_size = (((size+HBIN_HEADER_REC_SIZE) / REGF_ALLOC_BLOCK ) + 1 ) * REGF_ALLOC_BLOCK; 01514 01515 if ( !(hbin = regf_hbin_allocate( file, alloc_size )) ) { 01516 DEBUG(0,("find_free_space: regf_hbin_allocate() failed!\n")); 01517 return NULL; 01518 } 01519 DLIST_ADD( file->block_list, hbin ); 01520 } 01521 01522 done: 01523 /* set the offset to be ready to write */ 01524 01525 if ( !prs_set_offset( &hbin->ps, hbin->free_off-sizeof(uint32) ) ) 01526 return NULL; 01527 01528 /* write the record size as a placeholder for now, it should be 01529 probably updated by the caller once it all of the data necessary 01530 for the record */ 01531 01532 if ( !prs_uint32("allocated_size", &hbin->ps, 0, &size) ) 01533 return False; 01534 01535 update_free_space( hbin, size ); 01536 01537 return hbin; 01538 }
static uint32 sk_record_data_size | ( | SEC_DESC * | sd | ) | [static] |
参照先 sec_desc_size()・size.
参照元 regfio_write_key().
01544 { 01545 uint32 size, size_mod8; 01546 01547 size_mod8 = 0; 01548 01549 /* the record size is sizeof(hdr) + name + static members + data_size_field */ 01550 01551 size = sizeof(uint32)*5 + sec_desc_size( sd ) + sizeof(uint32); 01552 01553 /* multiple of 8 */ 01554 size_mod8 = size & 0xfffffff8; 01555 if ( size_mod8 < size ) 01556 size_mod8 += 8; 01557 01558 return size_mod8; 01559 }
static uint32 vk_record_data_size | ( | REGF_VK_REC * | vk | ) | [static] |
参照先 size・REGF_VK_REC::valuename.
参照元 regfio_write_key().
01565 { 01566 uint32 size, size_mod8; 01567 01568 size_mod8 = 0; 01569 01570 /* the record size is sizeof(hdr) + name + static members + data_size_field */ 01571 01572 size = REC_HDR_SIZE + (sizeof(uint16)*3) + (sizeof(uint32)*3) + sizeof(uint32); 01573 01574 if ( vk->valuename ) 01575 size += strlen(vk->valuename); 01576 01577 /* multiple of 8 */ 01578 size_mod8 = size & 0xfffffff8; 01579 if ( size_mod8 < size ) 01580 size_mod8 += 8; 01581 01582 return size_mod8; 01583 }
static uint32 lf_record_data_size | ( | uint32 | num_keys | ) | [static] |
参照先 size.
参照元 regfio_write_key().
01589 { 01590 uint32 size, size_mod8; 01591 01592 size_mod8 = 0; 01593 01594 /* the record size is sizeof(hdr) + num_keys + sizeof of hash_array + data_size_uint32 */ 01595 01596 size = REC_HDR_SIZE + sizeof(uint16) + (sizeof(REGF_HASH_REC) * num_keys) + sizeof(uint32); 01597 01598 /* multiple of 8 */ 01599 size_mod8 = size & 0xfffffff8; 01600 if ( size_mod8 < size ) 01601 size_mod8 += 8; 01602 01603 return size_mod8; 01604 }
static uint32 nk_record_data_size | ( | REGF_NK_REC * | nk | ) | [static] |
参照先 REGF_NK_REC::classname・REGF_NK_REC::keyname・size.
参照元 regfio_write_key().
01610 { 01611 uint32 size, size_mod8; 01612 01613 size_mod8 = 0; 01614 01615 /* the record size is static + length_of_keyname + length_of_classname + data_size_uint32 */ 01616 01617 size = 0x4c + strlen(nk->keyname) + sizeof(uint32); 01618 01619 if ( nk->classname ) 01620 size += strlen( nk->classname ); 01621 01622 /* multiple of 8 */ 01623 size_mod8 = size & 0xfffffff8; 01624 if ( size_mod8 < size ) 01625 size_mod8 += 8; 01626 01627 return size_mod8; 01628 }
static BOOL create_vk_record | ( | REGF_FILE * | file, | |
REGF_VK_REC * | vk, | |||
REGISTRY_VALUE * | value | |||
) | [static] |
参照先 REGF_VK_REC::data・REGF_VK_REC::data_off・REGF_VK_REC::data_size・find_free_space()・regf_hbin::first_hbin_off・REGF_VK_REC::flag・REGF_VK_REC::header・REGF_FILE::mem_ctx・name・regf_hbin::ps・regval_data_p()・regval_name()・regval_size()・regval_type()・talloc_strdup()・REGF_VK_REC::type・REGF_VK_REC::valuename.
参照元 regfio_write_key().
01634 { 01635 char *name = regval_name(value); 01636 REGF_HBIN *data_hbin; 01637 01638 ZERO_STRUCTP( vk ); 01639 01640 memcpy( vk->header, "vk", REC_HDR_SIZE ); 01641 01642 if ( name ) { 01643 vk->valuename = talloc_strdup( file->mem_ctx, regval_name(value) ); 01644 vk->flag = VK_FLAG_NAME_PRESENT; 01645 } 01646 01647 vk->data_size = regval_size( value ); 01648 vk->type = regval_type( value ); 01649 01650 if ( vk->data_size > sizeof(uint32) ) { 01651 uint32 data_size = ( (vk->data_size+sizeof(uint32)) & 0xfffffff8 ) + 8; 01652 01653 vk->data = (uint8 *)TALLOC_MEMDUP( file->mem_ctx, 01654 regval_data_p(value), 01655 vk->data_size ); 01656 if (vk->data == NULL) { 01657 return False; 01658 } 01659 01660 /* go ahead and store the offset....we'll pick this hbin block back up when 01661 we stream the data */ 01662 01663 if ((data_hbin = find_free_space(file, data_size )) == NULL) { 01664 return False; 01665 } 01666 vk->data_off = prs_offset( &data_hbin->ps ) + data_hbin->first_hbin_off - HBIN_HDR_SIZE; 01667 } 01668 else { 01669 /* make sure we don't try to copy from a NULL value pointer */ 01670 01671 if ( vk->data_size != 0 ) 01672 memcpy( &vk->data_off, regval_data_p(value), sizeof(uint32) ); 01673 vk->data_size |= VK_DATA_IN_OFFSET; 01674 } 01675 01676 return True; 01677 }
static int hashrec_cmp | ( | REGF_HASH_REC * | h1, | |
REGF_HASH_REC * | h2 | |||
) | [static] |
参照先 REGF_HASH_REC::fullname・StrCaseCmp().
参照元 regfio_write_key().
01683 { 01684 return StrCaseCmp( h1->fullname, h2->fullname ); 01685 }
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_VK_REC::hbin・_regf_sk_rec::hbin・REGF_LF_REC::hbin・REGF_NK_REC::hbin・REGF_VK_REC::hbin_off・REGF_LF_REC::hbin_off・_regf_sk_rec::hbin_off・REGF_NK_REC::hbin_off・hbin_prs_lf_records()・hbin_prs_vk_records()・REGF_LF_REC::header・_regf_sk_rec::header・REGF_NK_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_VK_REC::rec_size・REGF_LF_REC::rec_size・_regf_sk_rec::rec_size・REGF_NK_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_sk_rec::sec_desc・REGF_NK_REC::sec_desc・REGF_FILE::sec_desc_list・sec_desc_size()・_regf_sk_rec::size・size・_regf_sk_rec::sk_off・REGF_NK_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()・REGF_NK_REC::values・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 }