parse_prs.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,734 行 · 第 1/4 页
C
1,734 行
DEBUG(5,("\n")); ps->data_offset += (len * sizeof(uint16)); return True;}/****************************************************************** Start using a function for streaming unicode chars. If unmarshalling, output must be little-endian, if marshalling, input must be little-endian. ********************************************************************/static void dbg_rw_punival(BOOL charmode, const char *name, int depth, prs_struct *ps, char *in_buf, char *out_buf, int len){ int i; if (UNMARSHALLING(ps)) { if (ps->bigendian_data) { for (i = 0; i < len; i++) SSVAL(out_buf,2*i,RSVAL(in_buf, 2*i)); } else { for (i = 0; i < len; i++) SSVAL(out_buf, 2*i, SVAL(in_buf, 2*i)); } } else { if (ps->bigendian_data) { for (i = 0; i < len; i++) RSSVAL(in_buf, 2*i, SVAL(out_buf,2*i)); } else { for (i = 0; i < len; i++) SSVAL(in_buf, 2*i, SVAL(out_buf,2*i)); } } DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name)); if (charmode) print_asc(5, (unsigned char*)out_buf, 2*len); else { for (i = 0; i < len; i++) DEBUG(5,("%04x ", out_buf[i])); } DEBUG(5,("\n"));}/****************************************************************** Stream a unistr. Always little endian. ********************************************************************/BOOL prs_uint16uni(BOOL charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len){ char *q = prs_mem_get(ps, len * sizeof(uint16)); if (q == NULL) return False; dbg_rw_punival(charmode, name, depth, ps, q, (char *)data16s, len); ps->data_offset += (len * sizeof(uint16)); return True;}/****************************************************************** Stream an array of uint32s. Length is number of uint32s. ********************************************************************/BOOL prs_uint32s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len){ int i; char *q = prs_mem_get(ps, len * sizeof(uint32)); if (q == NULL) return False; if (UNMARSHALLING(ps)) { if (ps->bigendian_data) { for (i = 0; i < len; i++) data32s[i] = RIVAL(q, 4*i); } else { for (i = 0; i < len; i++) data32s[i] = IVAL(q, 4*i); } } else { if (ps->bigendian_data) { for (i = 0; i < len; i++) RSIVAL(q, 4*i, data32s[i]); } else { for (i = 0; i < len; i++) SIVAL(q, 4*i, data32s[i]); } } DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name)); if (charmode) print_asc(5, (unsigned char*)data32s, 4*len); else { for (i = 0; i < len; i++) DEBUG(5,("%08x ", data32s[i])); } DEBUG(5,("\n")); ps->data_offset += (len * sizeof(uint32)); return True;}/****************************************************************** Stream an array of unicode string, length/buffer specified separately, in uint16 chars. The unicode string is already in little-endian format. ********************************************************************/BOOL prs_buffer5(BOOL charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str){ char *p; char *q = prs_mem_get(ps, str->buf_len * sizeof(uint16)); if (q == NULL) return False; if (UNMARSHALLING(ps)) { str->buffer = PRS_ALLOC_MEM(ps,uint16,str->buf_len); if (str->buffer == NULL) return False; } /* If the string is empty, we don't have anything to stream */ if (str->buf_len==0) return True; p = (char *)str->buffer; dbg_rw_punival(charmode, name, depth, ps, q, p, str->buf_len); ps->data_offset += (str->buf_len * sizeof(uint16)); return True;}/****************************************************************** Stream a "not" unicode string, length/buffer specified separately, in byte chars. String is in little-endian format. ********************************************************************/BOOL prs_regval_buffer(BOOL charmode, const char *name, prs_struct *ps, int depth, REGVAL_BUFFER *buf){ char *p; char *q = prs_mem_get(ps, buf->buf_len); if (q == NULL) return False; if (UNMARSHALLING(ps)) { if (buf->buf_len > buf->buf_max_len) { return False; } if ( buf->buf_max_len ) { buf->buffer = PRS_ALLOC_MEM(ps, uint16, buf->buf_max_len); if ( buf->buffer == NULL ) return False; } } p = (char *)buf->buffer; dbg_rw_punival(charmode, name, depth, ps, q, p, buf->buf_len/2); ps->data_offset += buf->buf_len; return True;}/****************************************************************** Stream a string, length/buffer specified separately, in uint8 chars. ********************************************************************/BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STRING2 *str){ unsigned int i; char *q = prs_mem_get(ps, str->str_str_len); if (q == NULL) return False; if (UNMARSHALLING(ps)) { if (str->str_str_len > str->str_max_len) { return False; } str->buffer = PRS_ALLOC_MEM(ps,unsigned char, str->str_max_len); if (str->buffer == NULL) return False; } if (UNMARSHALLING(ps)) { for (i = 0; i < str->str_str_len; i++) str->buffer[i] = CVAL(q,i); } else { for (i = 0; i < str->str_str_len; i++) SCVAL(q, i, str->buffer[i]); } DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name)); if (charmode) print_asc(5, (unsigned char*)str->buffer, str->str_str_len); else { for (i = 0; i < str->str_str_len; i++) DEBUG(5,("%02x ", str->buffer[i])); } DEBUG(5,("\n")); ps->data_offset += str->str_str_len; return True;}/****************************************************************** Stream a unicode string, length/buffer specified separately, in uint16 chars. The unicode string is already in little-endian format. ********************************************************************/BOOL prs_unistr2(BOOL charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str){ char *p; char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16)); if (q == NULL) return False; /* If the string is empty, we don't have anything to stream */ if (str->uni_str_len==0) return True; if (UNMARSHALLING(ps)) { if (str->uni_str_len > str->uni_max_len) { return False; } str->buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_max_len); if (str->buffer == NULL) return False; } p = (char *)str->buffer; dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len); ps->data_offset += (str->uni_str_len * sizeof(uint16)); return True;}/****************************************************************** Stream a unicode string, length/buffer specified separately, in uint16 chars. The unicode string is already in little-endian format. ********************************************************************/BOOL prs_unistr3(BOOL charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth){ char *p; char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16)); if (q == NULL) return False; if (UNMARSHALLING(ps)) { str->str.buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_str_len); if (str->str.buffer == NULL) return False; } p = (char *)str->str.buffer; dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len); ps->data_offset += (str->uni_str_len * sizeof(uint16)); return True;}/******************************************************************* Stream a unicode null-terminated string. As the string is already in little-endian format then do it as a stream of bytes. ********************************************************************/BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str){ unsigned int len = 0; unsigned char *p = (unsigned char *)str->buffer; uint8 *start; char *q; uint32 max_len; uint16* ptr; if (MARSHALLING(ps)) { for(len = 0; str->buffer[len] != 0; len++) ; q = prs_mem_get(ps, (len+1)*2); if (q == NULL) return False; start = (uint8*)q; for(len = 0; str->buffer[len] != 0; len++) { if(ps->bigendian_data) { /* swap bytes - p is little endian, q is big endian. */ q[0] = (char)p[1]; q[1] = (char)p[0]; p += 2; q += 2; } else { q[0] = (char)p[0]; q[1] = (char)p[1]; p += 2; q += 2; } } /* * even if the string is 'empty' (only an \0 char) * at this point the leading \0 hasn't been parsed. * so parse it now */ q[0] = 0; q[1] = 0; q += 2; len++; DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name)); print_asc(5, (unsigned char*)start, 2*len); DEBUG(5, ("\n")); } else { /* unmarshalling */ uint32 alloc_len = 0; q = ps->data_p + prs_offset(ps); /* * Work out how much space we need and talloc it. */ max_len = (ps->buffer_size - ps->data_offset)/sizeof(uint16); /* the test of the value of *ptr helps to catch the circumstance where we have an emtpty (non-existent) string in the buffer */ for ( ptr = (uint16 *)q; *ptr++ && (alloc_len <= max_len); alloc_len++) /* do nothing */ ; if (alloc_len < max_len) alloc_len += 1; /* should we allocate anything at all? */ str->buffer = PRS_ALLOC_MEM(ps,uint16,alloc_len); if ((str->buffer == NULL) && (alloc_len > 0)) return False; p = (unsigned char *)str->buffer; len = 0; /* the (len < alloc_len) test is to prevent us from overwriting memory that is not ours...if we get that far, we have a non-null terminated string in the buffer and have messed up somewhere */ while ((len < alloc_len) && (*(uint16 *)q != 0)) { if(ps->bigendian_data) { /* swap bytes - q is big endian, p is little endian. */ p[0] = (unsigned char)q[1]; p[1] = (unsigned char)q[0]; p += 2; q += 2; } else { p[0] = (unsigned char)q[0]; p[1] = (unsigned char)q[1]; p += 2; q += 2; } len++; } if (len < alloc_len) { /* NULL terminate the UNISTR */ str->buffer[len++] = '\0'; } DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name)); print_asc(5, (unsigned char*)str->buffer, 2*len); DEBUG(5, ("\n")); } /* set the offset in the prs_struct; 'len' points to the terminiating NULL in the UNISTR so we need to go one more uint16 */ ps->data_offset += (len)*2; return True;}/******************************************************************* Stream a null-terminated string. len is strlen, and therefore does not include the null-termination character. ********************************************************************/BOOL prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size){ char *q; int i; int len; if (UNMARSHALLING(ps)) len = strlen(&ps->data_p[ps->data_offset]); else len = strlen(str); len = MIN(len, (max_buf_size-1)); q = prs_mem_get(ps, len+1); if (q == NULL) return False; for(i = 0; i < len; i++) { if (UNMARSHALLING(ps)) str[i] = q[i]; else q[i] = str[i]; } /* The terminating null. */ str[i] = '\0'; if (MARSHALLING(ps)) { q[i] = '\0'; } ps->data_offset += len+1; dump_data(5+depth, q, len);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?