Changeset 134 for trunk/lib/smb_deps.c
- Timestamp:
- 01/16/09 13:36:04 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/smb_deps.c
r132 r134 142 142 143 143 /* End of stuff from lib/time.c */ 144 145 /* From parse_prs.c */146 147 /*******************************************************************148 Attempt, if needed, to grow a data buffer.149 Also depends on the data stream mode (io).150 ********************************************************************/151 bool prs_grow(prs_struct *ps, uint32 extra_space)152 {153 uint32 new_size;154 char *new_data;155 156 ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space);157 158 if(ps->data_offset + extra_space <= ps->buffer_size)159 return true;160 161 /*162 * We cannot grow the buffer if we're not reading163 * into the prs_struct, or if we don't own the memory.164 */165 166 if(ps->io || !ps->is_dynamic)167 return false;168 169 /*170 * Decide how much extra space we really need.171 */172 extra_space -= (ps->buffer_size - ps->data_offset);173 if(ps->buffer_size == 0)174 {175 /*176 * Ensure we have at least a PDU's length, or extra_space,177 * whichever is greater.178 */179 new_size = MAX(MAX_PDU_FRAG_LEN,extra_space);180 181 if((new_data = zalloc(new_size)) == NULL)182 return false;183 }184 else185 {186 /*187 * If the current buffer size is bigger than the space needed, just188 * double it, else add extra_space.189 */190 new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);191 192 if ((new_data = (char*)realloc(ps->data_p, new_size)) == NULL)193 return false;194 195 memset(&new_data[ps->buffer_size], '\0',196 (size_t)(new_size - ps->buffer_size));197 }198 ps->buffer_size = new_size;199 ps->data_p = new_data;200 201 return true;202 }203 204 205 /*******************************************************************206 Align a the data_len to a multiple of align bytes - filling with207 zeros.208 ********************************************************************/209 bool prs_align(prs_struct *ps)210 {211 uint32 mod = ps->data_offset & (ps->align-1);212 213 if (ps->align != 0 && mod != 0)214 {215 uint32 extra_space = (ps->align - mod);216 if(!prs_grow(ps, extra_space))217 return false;218 memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);219 ps->data_offset += extra_space;220 }221 222 return true;223 }224 225 226 /**227 * Initialise an expandable parse structure.228 *229 * @param size Initial buffer size. If >0, a new buffer will be230 * created with malloc().231 *232 * @return false if allocation fails, otherwise true.233 **/234 235 bool prs_init(prs_struct *ps, uint32 size, void *ctx, bool io)236 {237 if(ps == NULL)238 return false;239 memset(ps, 0, sizeof(prs_struct));240 241 ps->io = io;242 ps->bigendian_data = RPC_LITTLE_ENDIAN;243 ps->align = RPC_PARSE_ALIGN;244 ps->is_dynamic = false;245 ps->data_offset = 0;246 ps->buffer_size = 0;247 ps->data_p = NULL;248 ps->mem_ctx = ctx;249 250 if (size != 0)251 {252 ps->buffer_size = size;253 if((ps->data_p = (char *)zalloc((size_t)size)) == NULL)254 return false;255 256 ps->is_dynamic = true; /* We own this memory. */257 }258 259 return true;260 }261 262 263 char *prs_mem_get(prs_struct *ps, uint32 extra_size)264 {265 if(ps->io)266 {267 /*268 * If reading, ensure that we can read the requested size item.269 */270 if (ps->data_offset + extra_size > ps->buffer_size)271 return NULL;272 }273 else274 {275 /*276 * Writing - grow the buffer if needed.277 */278 if(!prs_grow(ps, extra_size))279 return NULL;280 }281 282 return &ps->data_p[ps->data_offset];283 }284 285 286 /*******************************************************************287 Stream a uint32.288 ********************************************************************/289 bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32)290 {291 char *q = prs_mem_get(ps, sizeof(uint32));292 if (q == NULL)293 return false;294 295 if (ps->io)296 {297 if (ps->bigendian_data)298 *data32 = RIVAL(q,0);299 else300 *data32 = IVAL(q,0);301 }302 else303 {304 if (ps->bigendian_data)305 RSIVAL(q,0,*data32);306 else307 SIVAL(q,0,*data32);308 }309 ps->data_offset += sizeof(uint32);310 311 return true;312 }313 314 315 /******************************************************************316 Stream an array of uint32s. Length is number of uint32s.317 ********************************************************************/318 bool prs_uint32s(const char *name, prs_struct *ps,319 int depth, uint32 *data32s, int len)320 {321 int i;322 char *q = prs_mem_get(ps, len * sizeof(uint32));323 if (q == NULL)324 return false;325 326 if (ps->io)327 {328 if (ps->bigendian_data)329 {330 for (i = 0; i < len; i++)331 data32s[i] = RIVAL(q, 4*i);332 }333 else334 {335 for (i = 0; i < len; i++)336 data32s[i] = IVAL(q, 4*i);337 }338 }339 else340 {341 if (ps->bigendian_data)342 {343 for (i = 0; i < len; i++)344 RSIVAL(q, 4*i, data32s[i]);345 }346 else347 {348 for (i = 0; i < len; i++)349 SIVAL(q, 4*i, data32s[i]);350 }351 }352 ps->data_offset += (len * sizeof(uint32));353 354 return true;355 }356 357 358 /*******************************************************************359 Stream a uint16.360 ********************************************************************/361 bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16)362 {363 char *q = prs_mem_get(ps, sizeof(uint16));364 if (q == NULL)365 return false;366 367 if (ps->io)368 {369 if (ps->bigendian_data)370 *data16 = RSVAL(q,0);371 else372 *data16 = SVAL(q,0);373 }374 else375 {376 if (ps->bigendian_data)377 RSSVAL(q,0,*data16);378 else379 SSVAL(q,0,*data16);380 }381 ps->data_offset += sizeof(uint16);382 383 return true;384 }385 386 387 /*******************************************************************388 prs_uint16 wrapper. Call this and it sets up a pointer to where the389 uint16 should be stored, or gets the size if reading.390 ********************************************************************/391 bool prs_uint16_pre(const char *name, prs_struct *ps, int depth,392 uint16 *data16, uint32 *offset)393 {394 *offset = ps->data_offset;395 if (ps->io)396 {397 /* reading. */398 return prs_uint16(name, ps, depth, data16);399 }400 else401 {402 char *q = prs_mem_get(ps, sizeof(uint16));403 if(q ==NULL)404 return false;405 ps->data_offset += sizeof(uint16);406 }407 return true;408 }409 410 411 /*******************************************************************412 prs_uint16 wrapper. call this and it retrospectively stores the size.413 does nothing on reading, as that is already handled by ...._pre()414 ********************************************************************/415 bool prs_uint16_post(const char *name, prs_struct *ps, int depth,416 uint16 *data16, uint32 ptr_uint16, uint32 start_offset)417 {418 if (!ps->io)419 {420 /*421 * Writing - temporarily move the offset pointer.422 */423 uint16 data_size = ps->data_offset - start_offset;424 uint32 old_offset = ps->data_offset;425 426 ps->data_offset = ptr_uint16;427 if(!prs_uint16(name, ps, depth, &data_size))428 {429 ps->data_offset = old_offset;430 return false;431 }432 ps->data_offset = old_offset;433 }434 else435 ps->data_offset = start_offset + (uint32)(*data16);436 437 return true;438 }439 440 441 /*******************************************************************442 Stream a uint8.443 ********************************************************************/444 bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)445 {446 char *q = prs_mem_get(ps, 1);447 if (q == NULL)448 return false;449 450 if (ps->io)451 *data8 = CVAL(q,0);452 else453 SCVAL(q,0,*data8);454 455 ps->data_offset += 1;456 457 return true;458 }459 460 461 /******************************************************************462 Stream an array of uint8s. Length is number of uint8s.463 ********************************************************************/464 bool prs_uint8s(const char *name, prs_struct *ps, int depth,465 uint8* data8s, int len)466 {467 int i;468 char *q = prs_mem_get(ps, len);469 if (q == NULL)470 return false;471 472 if (ps->io)473 {474 for (i = 0; i < len; i++)475 data8s[i] = CVAL(q,i);476 }477 else478 {479 for (i = 0; i < len; i++)480 SCVAL(q, i, data8s[i]);481 }482 483 ps->data_offset += len;484 485 return true;486 }487 488 489 /*******************************************************************490 Set the current offset (external interface).491 ********************************************************************/492 bool prs_set_offset(prs_struct *ps, uint32 offset)493 {494 if(offset <= ps->data_offset)495 {496 ps->data_offset = offset;497 return true;498 }499 500 if(!prs_grow(ps, offset - ps->data_offset))501 return false;502 503 ps->data_offset = offset;504 return true;505 }506 507 /* End of stuff from parse_prs.c */508 509 /* From rpc_parse/parse_misc.c */510 511 /*******************************************************************512 Reads or writes a struct uuid513 ********************************************************************/514 bool smb_io_uuid(const char *desc, struct uuid *uuid,515 prs_struct *ps, int depth)516 {517 if (uuid == NULL)518 return false;519 depth++;520 521 if(!prs_uint32 ("data ", ps, depth, &uuid->time_low))522 return false;523 if(!prs_uint16 ("data ", ps, depth, &uuid->time_mid))524 return false;525 if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version))526 return false;527 528 if(!prs_uint8s ("data ", ps, depth,529 uuid->clock_seq, sizeof(uuid->clock_seq)))530 return false;531 532 if(!prs_uint8s ("data ", ps, depth, uuid->node, sizeof(uuid->node)))533 return false;534 535 return true;536 }537 538 539 /*******************************************************************540 Reads or writes an NTTIME structure.541 ********************************************************************/542 bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)543 {544 if (nttime == NULL)545 return false;546 depth++;547 548 if(!prs_align(ps))549 return false;550 551 if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */552 return false;553 if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */554 return false;555 556 return true;557 }
Note: See TracChangeset
for help on using the changeset viewer.