registry/regfio.c

ソースコードを見る。

関数

static int write_block (REGF_FILE *file, prs_struct *ps, uint32 offset)
static int read_block (REGF_FILE *file, prs_struct *ps, uint32 file_offset, uint32 block_size)
static BOOL write_hbin_block (REGF_FILE *file, REGF_HBIN *hbin)
static BOOL hbin_block_close (REGF_FILE *file, REGF_HBIN *hbin)
static BOOL prs_regf_block (const char *desc, prs_struct *ps, int depth, REGF_FILE *file)
static BOOL prs_hbin_block (const char *desc, prs_struct *ps, int depth, REGF_HBIN *hbin)
static BOOL prs_nk_rec (const char *desc, prs_struct *ps, int depth, REGF_NK_REC *nk)
static uint32 regf_block_checksum (prs_struct *ps)
static BOOL read_regf_block (REGF_FILE *file)
static REGF_HBINread_hbin_block (REGF_FILE *file, off_t offset)
static BOOL hbin_contains_offset (REGF_HBIN *hbin, uint32 offset)
static REGF_HBINlookup_hbin_block (REGF_FILE *file, uint32 offset)
static BOOL prs_hash_rec (const char *desc, prs_struct *ps, int depth, REGF_HASH_REC *hash)
static BOOL hbin_prs_lf_records (const char *desc, REGF_HBIN *hbin, int depth, REGF_NK_REC *nk)
static BOOL hbin_prs_sk_rec (const char *desc, REGF_HBIN *hbin, int depth, REGF_SK_REC *sk)
static BOOL hbin_prs_vk_rec (const char *desc, REGF_HBIN *hbin, int depth, REGF_VK_REC *vk, REGF_FILE *file)
static BOOL hbin_prs_vk_records (const char *desc, REGF_HBIN *hbin, int depth, REGF_NK_REC *nk, REGF_FILE *file)
static REGF_SK_RECfind_sk_record_by_offset (REGF_FILE *file, uint32 offset)
static REGF_SK_RECfind_sk_record_by_sec_desc (REGF_FILE *file, SEC_DESC *sd)
static BOOL hbin_prs_key (REGF_FILE *file, REGF_HBIN *hbin, REGF_NK_REC *nk)
static BOOL next_record (REGF_HBIN *hbin, const char *hdr, BOOL *eob)
static BOOL next_nk_record (REGF_FILE *file, REGF_HBIN *hbin, REGF_NK_REC *nk, BOOL *eob)
static BOOL init_regf_block (REGF_FILE *file)
REGF_FILEregfio_open (const char *filename, int flags, int mode)
static void regfio_mem_free (REGF_FILE *file)
int regfio_close (REGF_FILE *file)
static void regfio_flush (REGF_FILE *file)
REGF_NK_RECregfio_rootkey (REGF_FILE *file)
REGF_NK_RECregfio_fetch_subkey (REGF_FILE *file, REGF_NK_REC *nk)
static REGF_HBINregf_hbin_allocate (REGF_FILE *file, uint32 block_size)
static void update_free_space (REGF_HBIN *hbin, uint32 size_used)
static REGF_HBINfind_free_space (REGF_FILE *file, uint32 size)
static uint32 sk_record_data_size (SEC_DESC *sd)
static uint32 vk_record_data_size (REGF_VK_REC *vk)
static uint32 lf_record_data_size (uint32 num_keys)
static uint32 nk_record_data_size (REGF_NK_REC *nk)
static BOOL create_vk_record (REGF_FILE *file, REGF_VK_REC *vk, REGISTRY_VALUE *value)
static int hashrec_cmp (REGF_HASH_REC *h1, REGF_HASH_REC *h2)
REGF_NK_RECregfio_write_key (REGF_FILE *file, const char *name, REGVAL_CTR *values, REGSUBKEY_CTR *subkeys, SEC_DESC *sec_desc, REGF_NK_REC *parent)


関数

static int write_block ( REGF_FILE file,
prs_struct ps,
uint32  offset 
) [static]

regfio.c34 行で定義されています。

参照先 errnoREGF_FILE::fdstrerror()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]

regfio.c72 行で定義されています。

参照先 errnoREGF_FILE::fdREGF_FILE::mem_ctxprs_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 }

static BOOL write_hbin_block ( REGF_FILE file,
REGF_HBIN hbin 
) [static]

regfio.c147 行で定義されています。

参照先 regf_hbin::dirtyregf_hbin::file_offregf_hbin::free_offregf_hbin::free_sizeregf_hbin::pswrite_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 }

static BOOL hbin_block_close ( REGF_FILE file,
REGF_HBIN hbin 
) [static]

regfio.c173 行で定義されています。

参照先 REGF_FILE::block_listregf_hbin::nextwrite_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]

regfio.c197 行で定義されています。

参照先 REGF_FILE::checksumREGF_FILE::data_offsetREGF_FILE::headerREGF_FILE::last_blockREGF_FILE::mtimeprs_debug()smb_io_time()REGF_FILE::unknown1REGF_FILE::unknown2REGF_FILE::unknown3REGF_FILE::unknown4REGF_FILE::unknown5REGF_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]

regfio.c257 行で定義されています。

参照先 regf_hbin::block_sizeregf_hbin::dirtyregf_hbin::first_hbin_offregf_hbin::headerprs_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]

regfio.c292 行で定義されています。

参照先 REGF_NK_REC::classnameREGF_NK_REC::classname_offregf_hbin::dirtyREGF_NK_REC::hbinREGF_NK_REC::hbin_offREGF_NK_REC::headerREGF_NK_REC::key_typeREGF_NK_REC::keynameREGF_NK_REC::max_bytes_subkeyclassnameREGF_NK_REC::max_bytes_subkeynameREGF_NK_REC::max_bytes_valueREGF_NK_REC::max_bytes_valuenameREGF_NK_REC::mtimeREGF_NK_REC::num_subkeysREGF_NK_REC::num_valuesREGF_NK_REC::parent_offprs_debug()REGF_NK_REC::rec_sizeREGF_NK_REC::sk_offsmb_io_time()REGF_NK_REC::subkeys_offREGF_NK_REC::unk_indexREGF_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]

regfio.c398 行で定義されています。

参照元 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 }

static BOOL read_regf_block ( REGF_FILE file  )  [static]

regfio.c419 行で定義されています。

参照先 REGF_FILE::checksumprs_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 }

static REGF_HBIN* read_hbin_block ( REGF_FILE file,
off_t  offset 
) [static]

regfio.c449 行で定義されています。

参照先 REGF_FILE::data_offsetregf_hbin::file_offregf_hbin::free_offregf_hbin::free_sizeREGF_FILE::mem_ctxprs_hbin_block()regf_hbin::psread_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 }

static BOOL hbin_contains_offset ( REGF_HBIN hbin,
uint32  offset 
) [static]

regfio.c540 行で定義されています。

参照先 regf_hbin::block_sizeregf_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 }

static REGF_HBIN* lookup_hbin_block ( REGF_FILE file,
uint32  offset 
) [static]

regfio.c556 行で定義されています。

参照先 REGF_FILE::block_listregf_hbin::block_sizeregf_hbin::file_offhbin_contains_offset()regf_hbin::nextprs_mem_free()regf_hbin::psread_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]

regfio.c595 行で定義されています。

参照先 REGF_HASH_REC::keycheckREGF_HASH_REC::nk_offprs_debug().

参照元 hbin_prs_lf_records().

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]

regfio.c611 行で定義されています。

参照先 regf_hbin::dirtyregf_hbin::first_hbin_offREGF_LF_REC::hashesREGF_LF_REC::headerREGF_LF_REC::num_keysREGF_NK_REC::num_subkeysprs_debug()prs_hash_rec()regf_hbin::psREGF_LF_REC::rec_sizeREGF_NK_REC::subkeysREGF_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]

regfio.c675 行で定義されています。

参照先 regf_hbin::dirtyregf_hbin::first_hbin_off_regf_sk_rec::header_regf_sk_rec::next_sk_off_regf_sk_rec::prev_sk_offprs_debug()regf_hbin::ps_regf_sk_rec::rec_size_regf_sk_rec::ref_count_regf_sk_rec::sec_descsec_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]

regfio.c730 行で定義されています。

参照先 REGF_VK_REC::dataREGF_VK_REC::data_offREGF_VK_REC::data_sizeregf_hbin::dirtyregf_hbin::first_hbin_offREGF_VK_REC::flaghbin_contains_offset()REGF_VK_REC::headerlookup_hbin_block()prs_debug()regf_hbin::psREGF_VK_REC::rec_sizeREGF_VK_REC::typeREGF_VK_REC::valuename.

参照元 hbin_prs_vk_records().

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]

regfio.c847 行で定義されています。

参照先 regf_hbin::first_hbin_offhbin_contains_offset()REGF_VK_REC::hbin_offhbin_prs_vk_rec()lookup_hbin_block()REGF_NK_REC::num_valuesprs_debug()regf_hbin::psREGF_VK_REC::rec_offREGF_NK_REC::valuesREGF_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]

regfio.c914 行で定義されています。

参照先 _regf_sk_rec::nextREGF_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]

regfio.c929 行で定義されています。

参照先 _regf_sk_rec::next_regf_sk_rec::sec_descsec_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]

regfio.c946 行で定義されています。

参照先 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_ctxREGF_NK_REC::num_subkeysREGF_NK_REC::num_valuesprs_debug()prs_nk_rec()regf_hbin::psREGF_NK_REC::sec_descREGF_FILE::sec_desc_list_regf_sk_rec::sk_offREGF_NK_REC::sk_offREGF_NK_REC::subkeys_offREGF_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 }

static BOOL next_record ( REGF_HBIN hbin,
const char *  hdr,
BOOL eob 
) [static]

regfio.c1025 行で定義されています。

参照先 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]

regfio.c1088 行で定義されています。

参照先 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 }

static BOOL init_regf_block ( REGF_FILE file  )  [static]

regfio.c1101 行で定義されています。

参照先 REGF_FILE::checksumREGF_FILE::data_offsetREGF_FILE::headerREGF_FILE::last_blockREGF_FILE::mem_ctxREGF_FILE::mtimeprs_init()prs_mem_free()prs_regf_block()regf_block_checksum()resultunix_to_nt_time()REGF_FILE::unknown1REGF_FILE::unknown2REGF_FILE::unknown3REGF_FILE::unknown4REGF_FILE::unknown5REGF_FILE::unknown6write_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 
)

regfio.c1159 行で定義されています。

参照先 errnoREGF_FILE::fdinit_regf_block()REGF_FILE::mem_ctxREGF_FILE::open_flagsread_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]

regfio.c1214 行で定義されています。

参照先 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  ) 

regfio.c1225 行で定義されています。

参照先 REGF_FILE::block_listREGF_FILE::checksumREGF_FILE::fdfd_regf_sk_rec::hbinhbin_block_close()hbin_prs_sk_rec()REGF_FILE::mtime_regf_sk_rec::nextREGF_FILE::open_flagsprs_mem_free()prs_regf_block()read_block()regf_block_checksum()regfio_mem_free()REGF_FILE::sec_desc_listunix_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]

regfio.c1288 行で定義されています。

参照先 REGF_FILE::block_listregf_hbin::nextwrite_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  ) 

regfio.c1302 行で定義されています。

参照先 REGF_FILE::block_listregf_hbin::block_sizeREGF_NK_REC::key_typeREGF_FILE::mem_ctxnext_nk_record()prs_mem_free()regf_hbin::psread_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 
)

regfio.c1357 行で定義されています。

参照先 regf_hbin::first_hbin_offREGF_LF_REC::hasheshbin_prs_key()lookup_hbin_block()REGF_FILE::mem_ctxREGF_HASH_REC::nk_offREGF_NK_REC::num_subkeysregf_hbin::psREGF_NK_REC::subkey_indexREGF_NK_REC::subkeysREGF_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 }

static REGF_HBIN* regf_hbin_allocate ( REGF_FILE file,
uint32  block_size 
) [static]

regfio.c1394 行で定義されています。

参照先 regf_hbin::block_sizeerrnoREGF_FILE::fdregf_hbin::file_offregf_hbin::first_hbin_offregf_hbin::free_offregf_hbin::free_sizeregf_hbin::headerREGF_FILE::last_blockREGF_FILE::mem_ctxprs_hbin_block()prs_init()regf_hbin::psstrerror()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]

regfio.c1435 行で定義されています。

参照先 regf_hbin::block_sizeregf_hbin::free_offregf_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 }

static REGF_HBIN* find_free_space ( REGF_FILE file,
uint32  size 
) [static]

regfio.c1450 行で定義されています。

参照先 REGF_FILE::block_listregf_hbin::block_sizeregf_hbin::file_offregf_hbin::free_offregf_hbin::free_sizeregf_hbin::nextprs_mem_free()regf_hbin::psread_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]

regfio.c1543 行で定義されています。

参照先 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]

regfio.c1564 行で定義されています。

参照先 sizeREGF_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]

regfio.c1588 行で定義されています。

参照先 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]

regfio.c1609 行で定義されています。

参照先 REGF_NK_REC::classnameREGF_NK_REC::keynamesize.

参照元 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]

regfio.c1633 行で定義されています。

参照先 REGF_VK_REC::dataREGF_VK_REC::data_offREGF_VK_REC::data_sizefind_free_space()regf_hbin::first_hbin_offREGF_VK_REC::flagREGF_VK_REC::headerREGF_FILE::mem_ctxnameregf_hbin::psregval_data_p()regval_name()regval_size()regval_type()talloc_strdup()REGF_VK_REC::typeREGF_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]

regfio.c1682 行で定義されています。

参照先 REGF_HASH_REC::fullnameStrCaseCmp().

参照元 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 
)

regfio.c1690 行で定義されています。

参照先 REGF_NK_REC::classnameREGF_NK_REC::classname_offcreate_vk_record()regf_hbin::file_offfind_free_space()find_sk_record_by_sec_desc()regf_hbin::first_hbin_offREGF_HASH_REC::fullnameREGF_LF_REC::hasheshashrec_cmp()REGF_VK_REC::hbin_regf_sk_rec::hbinREGF_LF_REC::hbinREGF_NK_REC::hbinREGF_VK_REC::hbin_offREGF_LF_REC::hbin_off_regf_sk_rec::hbin_offREGF_NK_REC::hbin_offhbin_prs_lf_records()hbin_prs_vk_records()REGF_LF_REC::header_regf_sk_rec::headerREGF_NK_REC::headerREGF_NK_REC::key_typeREGF_HASH_REC::keycheckREGF_NK_REC::keynamelf_record_data_size()REGF_NK_REC::max_bytes_subkeynameREGF_NK_REC::max_bytes_valueREGF_NK_REC::max_bytes_valuenameREGF_FILE::mem_ctxREGF_NK_REC::mtime_regf_sk_rec::next_sk_offREGF_HASH_REC::nk_offnk_record_data_size()REGF_LF_REC::num_keysREGF_NK_REC::num_subkeysREGF_NK_REC::num_valuesREGF_NK_REC::parent_off_regf_sk_rec::prev_regf_sk_rec::prev_sk_offprs_nk_rec()regf_hbin::psREGF_VK_REC::rec_offREGF_VK_REC::rec_sizeREGF_LF_REC::rec_size_regf_sk_rec::rec_sizeREGF_NK_REC::rec_size_regf_sk_rec::ref_countregfio_flush()regsubkey_ctr_numkeys()regsubkey_ctr_specific_key()regval_ctr_numvals()regval_ctr_specific_value()regval_name()regval_size()_regf_sk_rec::sec_descREGF_NK_REC::sec_descREGF_FILE::sec_desc_listsec_desc_size()_regf_sk_rec::sizesize_regf_sk_rec::sk_offREGF_NK_REC::sk_offsk_record_data_size()REGF_NK_REC::subkey_indexREGF_NK_REC::subkeysREGF_NK_REC::subkeys_offtalloc_strdup()unix_to_nt_time()REGF_NK_REC::valuesvaluesREGF_NK_REC::values_offvk_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 }


Sambaに対してSat Aug 29 21:24:06 2009に生成されました。  doxygen 1.4.7