static XC_ALLOCATOR_INIT(xc_allocator_bestfit_init) /* {{{ */ { xc_allocator_bestfit_block_t *b; #define MINSIZE (ALIGN(sizeof(xc_allocator_bestfit_t)) + sizeof(xc_allocator_bestfit_block_t)) /* requires at least the header and 1 tail block */ if (size < MINSIZE) { fprintf(stderr, "xc_allocator_bestfit_init requires %lu bytes at least\n", (unsigned long) MINSIZE); return NULL; } TRACE("size=%lu", size); allocator->shm = shm; allocator->size = size; allocator->avail = size - MINSIZE; /* pointer to first block, right after ALIGNed header */ b = allocator->headblock; xc_block_setup(b, 0, (xc_allocator_bestfit_block_t *) PADD(allocator, ALIGN(sizeof(xc_allocator_bestfit_t)))); /* first block*/ b = b->next; xc_block_setup(b, allocator->avail, 0); #undef MINSIZE return allocator; }
/* }}} */ static XC_ALLOCATOR_FREE(xc_allocator_bestfit_free) /* {{{ return block size freed */ { xc_allocator_bestfit_block_t *cur, *b; int size; cur = (xc_allocator_bestfit_block_t *) (CHAR_PTR(p) - BLOCK_HEADER_SIZE()); TRACE("freeing: %p, size=%lu", p, cur->size); xc_block_check(cur); assert((char*)allocator < (char*)cur); assert((char*)cur < (char*)allocator + allocator->size); /* find free block right before the p */ b = allocator->headblock; while (b->next != 0 && b->next < cur) { b = b->next; } /* restore block */ cur->next = b->next; b->next = cur; size = cur->size; TRACE(" avail %lu (%luKB)", allocator->avail, allocator->avail / 1024); allocator->avail += size; /* combine prev|cur */ if (PADD(b, b->size) == (char *)cur) { b->size += cur->size; b->next = cur->next; cur = b; TRACE("%s", " combine prev"); } /* combine cur|next */ b = cur->next; if (PADD(cur, cur->size) == (char *)b) { cur->size += b->size; cur->next = b->next; TRACE("%s", " combine next"); } TRACE(" -> avail %lu (%luKB)", allocator->avail, allocator->avail / 1024); return size; }
static int RtsmbWireVarEncodeWriteCommandCb(smb2_stream *pStream, PFVOID origin, PFVOID buf, rtsmb_size size,PFVOID pItem) { PRTSMB2_WRITE_C pCommand = (PRTSMB2_WRITE_C) pItem; int rv; PFVOID s=buf; rv = RtsmbWireVarEncode (pStream, origin, buf, size, pCommand->DataOffset, pCommand->Length, pCommand->StructureSize); if (rv >= 0) { HEREHERE // This may be reversed, need validation if (pCommand->WriteChannelInfoLength) { dword UsedSize; buf = PADD(buf, rv); size = size - (rtsmb_size) rv; UsedSize = (dword) PDIFF (buf, s); rv = RtsmbWireVarEncodePartTwo(pStream, origin, buf, size, pCommand->WriteChannelInfoOffset, pCommand->WriteChannelInfoLength, UsedSize); } }
static int RtsmbWireVarEncodeCreateCommandCb(smb2_stream *pStream, PFVOID origin, PFVOID buf, rtsmb_size size,PFVOID pItem) { PFVOID s=buf; PRTSMB2_CREATE_C pCommand = (PRTSMB2_CREATE_C) pItem; int rv; rv = RtsmbWireVarEncode (pStream, origin, buf, size, pCommand->NameOffset, pCommand->NameLength, pCommand->StructureSize); if (rv >= 0) { if (pCommand->CreateContextsLength) { dword UsedSize; buf = PADD(buf, rv); size -= (rtsmb_size) rv; UsedSize = (dword) PDIFF (buf, s); rv = RtsmbWireVarEncodePartTwo(pStream, origin, buf, size, pCommand->CreateContextsOffset, pCommand->CreateContextsLength, UsedSize); } } return rv; }
int rtsmb_net_write_datagram (RTP_SOCKET socket, PFBYTE remote, int port, PFVOID buf, int size) { int bytes_sent; int rv = 0; do { bytes_sent = rtp_net_sendto(socket, buf,size,remote,port, 4); if (bytes_sent < 0) /* an error occurred */ { rv = -1; break; } size -= bytes_sent; buf = PADD (buf, bytes_sent); } while (size > 0); return rv; }
/** * Blocks until |size| bytes from buf have been sent. * * Returns -1 if an error occurs, 0 else. */ int rtsmb_net_write (RTP_SOCKET socket, PFVOID buf, int size) { int bytes_sent; int rv = 0; do { bytes_sent = rtp_net_send(socket, buf, size); if (bytes_sent < 0) /* an error occurred */ { rv = -1; break; } size -= bytes_sent; buf = PADD (buf, bytes_sent); } while (size > 0); return rv; }
/* Offset of first EIF_CHARACTER_8. */ rt_public size_t eif_chroff(size_t nb_ref) { size_t to_add = REFACS(nb_ref); return to_add + PADD(to_add, CHRSIZ); }
/* ================ PFBYTE inBuf - The start of the incoming buffer (needed for offset calculations) PSMB_TRANSACTIONRQ pInReq - the incoming request PFBYTE outBuf - the outgoing buffer (needed for offset calculations) PSMB_TRANSACTIONRS pOutRes - The out going transaction response ================ */ int RAP_Proc (PSMB_SESSIONCTX pCtx, PRTSMB_HEADER pInHdr, PRTSMB_TRANSACTION pTransaction, PFVOID pInBuf, PRTSMB_HEADER pOutHdr, PRTSMB_TRANSACTION_R pTransactionR, rtsmb_size size_left) { RTSMB_RAP_REQUEST func; rtsmb_char param [50]; rtsmb_char answer [50]; int size, data_size = 0; word param_size; func.parent = pTransaction; func.parameter = param; func.parameter_size = 49; func.answer = answer; func.answer_size = 49; size = srv_cmd_read_rap_request (pCtx->read_origin, pInBuf, pCtx->current_body_size - (rtsmb_size)(PDIFF (pInBuf, pCtx->read_origin)), pInHdr, &func); if (size == -1) return 0; pInBuf = PADD (pInBuf, size); param_size = 0; switch (func.opcode) { case RAP_COM_NET_SHARE_ENUM: data_size = NetShareEnum (pCtx, &func, pInHdr, pInBuf, pOutHdr, size_left, ¶m_size); break; case RAP_COM_NET_SERVER_GETINFO: data_size = NetServerGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr, size_left, ¶m_size); break; case RAP_COM_NET_WKSTA_GETINFO: data_size = NetWkstaGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr, size_left, ¶m_size); break; case RAP_COM_NET_SHARE_GETINFO: data_size = NetShareGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr, size_left, ¶m_size); break; case RAP_COM_WPRINTQ_GETINFO: data_size = WPrintQGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr, size_left, ¶m_size); break; case RAP_COM_NET_SERVER_ENUM2: data_size = NetServerEnum2 (pCtx, &func, pInHdr, pInBuf, pOutHdr, size_left, ¶m_size); break; /* case RAP_COM_NET_ACCESS_GETINFO: NetAccessGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr, size_left); break;*/ default: RTSMB_DEBUG_OUTPUT_STR ("RAP_Proc: function unhandled: ", RTSMB_DEBUG_TYPE_ASCII); RTSMB_DEBUG_OUTPUT_INT (func.opcode); RTSMB_DEBUG_OUTPUT_STR ("\n", RTSMB_DEBUG_TYPE_ASCII); } if (data_size == -2) /* special error case where we don't want to answer */ return -1; pTransactionR->setup_size = 0; pTransactionR->setup = (PFWORD)0; pTransactionR->parameter = pCtx->tmpBuffer; pTransactionR->parameter_count = param_size; if (data_size == -1) { pTransactionR->data = (PFBYTE)0; pTransactionR->data_count = 0; } else { pTransactionR->data = PADD (pCtx->tmpBuffer, param_size); pTransactionR->data_count = (word) data_size; } return 0; } // End RAP_Proc
int NetShareGetInfo (PSMB_SESSIONCTX pCtx, PRTSMB_RAP_REQUEST pFunc, PRTSMB_HEADER pInHdr, PFVOID pInBuf, PRTSMB_HEADER pOutHdr, rtsmb_size size_left, PFWORD param_size) { PSR_RESOURCE pResource; RTSMB_RAP_SHARE_GET_INFO command; RTSMB_RAP_RESPONSE response; PFVOID data_section; PFVOID pOutBuf = pCtx->tmpBuffer; rtsmb_char share[RTSMB_MAX_SHARENAME_SIZE + 1]; int r, id; command.share = share; command.share_size = RTSMB_MAX_SHARENAME_SIZE; r = srv_cmd_read_rap_share_get_info (pCtx->write_origin, pInBuf, pCtx->current_body_size - (rtsmb_size)(PDIFF (pInBuf, pCtx->read_origin)), pInHdr, &command); if (r == -1) return -1; size_left = MIN (command.receive_size, size_left); // Fill out parameters response.status = RAP_ERROR_ACCESS_DENIED; response.converter = 0; response.available_bytes = 0; r = srv_cmd_fill_rap_response (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &response); if (r == -1) return r; size_left -= (rtsmb_size) r; *param_size = (word) r; pOutBuf = PADD (pCtx->tmpBuffer, r); data_section = pOutBuf; id = SR_GetTreeIdFromName (command.share); CLAIM_SHARE (); if (id > -1) { pResource = SR_ResourceById ((word) id); switch (command.information_level) { case 0: { RTSMB_RAP_SHARE_INFO_0 info; rtsmb_ncpy (info.name, pResource->name, 12); info.name[12] = '\0'; r = srv_cmd_fill_rap_share_info_0 (pCtx->write_origin, pOutBuf, size_left, pOutHdr, &info); } break; case 1: { RTSMB_RAP_SHARE_INFO_1 info; rtsmb_ncpy (info.name, pResource->name, 12); info.name[12] = '\0'; info.type = pResource->stype; info.comment = pResource->comment; r = srv_cmd_fill_rap_share_info_1 (pCtx->write_origin, pOutBuf, size_left, pOutHdr, &info); } break; default: r = 0; break; } } else r = 0; RELEASE_SHARE (); if (r == -1) { response.status = RAP_NERR_BUFTOOSMALL; response.converter = 0; r = 0; } else { response.status = RAP_NERR_SUCCESS; response.converter = (word)((int) data_section) & 0xFFFF; } response.available_bytes = (word) r; srv_cmd_fill_rap_response (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &response); return r; } // End NetShareGetInfo
int WPrintQGetInfo (PSMB_SESSIONCTX pCtx, PRTSMB_RAP_REQUEST pFunc, PRTSMB_HEADER pInHdr, PFVOID pInBuf, PRTSMB_HEADER pOutHdr, rtsmb_size size_left, PFWORD param_size) { PSR_RESOURCE pOutRes; RTSMB_RAP_SHARE_GET_INFO command; RTSMB_RAP_RESPONSE response; PFVOID data_section; PFVOID pOutBuf = pCtx->tmpBuffer; rtsmb_char share[RTSMB_MAX_SHARENAME_SIZE + 1]; word status = RAP_NERR_SUCCESS; int r; rtsmb_size desired_size; rtsmb_size original_size_left = size_left; command.share = share; command.share_size = RTSMB_MAX_SHARENAME_SIZE; r = srv_cmd_read_rap_share_get_info (pCtx->write_origin, pInBuf, pCtx->current_body_size - (rtsmb_size)PDIFF (pInBuf, pCtx->read_origin), pInHdr, &command); if (r == -1) return -1; size_left = MIN (command.receive_size, original_size_left); // Fill out parameters response.status = RAP_ERROR_ACCESS_DENIED; response.converter = 0; response.available_bytes = 0; r = srv_cmd_fill_rap_response (pCtx->tmpBuffer, pCtx->tmpBuffer, original_size_left, pOutHdr, &response); if (r == -1) { return 0; } *param_size = (word)r; pOutBuf = PADD (pCtx->tmpBuffer, r); data_section = pOutBuf; CLAIM_SHARE (); // find printer share for(pOutRes = SR_FirstResource(); pOutRes != (PSR_RESOURCE)0; pOutRes = SR_NextResource(pOutRes)) { if (rtsmb_casecmp (pOutRes->name, command.share, CFG_RTSMB_USER_CODEPAGE) == 0) { break; } } if (!pOutRes) { status = RAP_ERROR_ACCESS_DENIED; } else { switch (command.information_level) { case 0: { RTSMB_RAP_PRINTER_QUEUE_INFO_0 info; rtsmb_ncpy (info.name, pOutRes->name, 12); info.name[12] = '\0'; desired_size = srv_cmd_sizeof_rap_printer_queue_info_0 (pOutHdr, &info); r = srv_cmd_fill_rap_printer_queue_info_0 (pCtx->tmpBuffer, pOutBuf, size_left, pOutHdr, &info); } break; case 1: case 2: { RTSMB_RAP_PRINTER_QUEUE_INFO_1 info; rtsmb_char preproc[] = {'W', 'i', 'n', 'P', 'r', 'i', 'n', 't', '\0'}; info.priority = 1; info.start_time = 0; info.until_time = 0; info.status = PRQ_ACTIVE; info.num_jobs = 0; rtsmb_ncpy (info.name, pOutRes->name, 12); info.name[12] = '\0'; info.preprocessor = preproc; info.comment = pOutRes->comment; info.sep_file = (PFRTCHAR)0; info.parameters = (PFRTCHAR)0; info.destinations = (PFRTCHAR)0; desired_size = srv_cmd_sizeof_rap_printer_queue_info_1 (pOutHdr, &info); r = srv_cmd_fill_rap_printer_queue_info_1 (pCtx->tmpBuffer, pOutBuf, size_left, pOutHdr, &info); } break; case 3: case 4: { RTSMB_RAP_PRINTER_QUEUE_INFO_3 info; rtsmb_char preproc[] = {'W', 'i', 'n', 'P', 'r', 'i', 'n', 't', '\0'}; info.priority = 1; info.start_time = 0; info.until_time = 0; info.status = PRQ_ACTIVE; info.num_jobs = 0; info.name = pOutRes->name; info.comment = pOutRes->comment; info.driver_name = pOutRes->u.printer.printerfile; info.preprocessor = preproc; info.sep_file = (PFRTCHAR)0; info.parameters = (PFRTCHAR)0; info.printers = (PFRTCHAR)0; info.driver_data = (PFRTCHAR)0; desired_size = srv_cmd_sizeof_rap_printer_queue_info_3 (pOutHdr, &info); r = srv_cmd_fill_rap_printer_queue_info_3 (pCtx->tmpBuffer, pOutBuf, size_left, pOutHdr, &info); } break; case 5: { RTSMB_RAP_PRINTER_QUEUE_INFO_5 info; info.name = pOutRes->name; desired_size = srv_cmd_sizeof_rap_printer_queue_info_5 (pOutHdr, &info); r = srv_cmd_fill_rap_printer_queue_info_5 (pCtx->tmpBuffer, pOutBuf, size_left, pOutHdr, &info); } break; } } RELEASE_SHARE (); if (r == -1) { response.status = RAP_NERR_BUFTOOSMALL; response.converter = 0; response.available_bytes = (word)desired_size; r = 0; } else { response.status = status; response.converter = (word)(((int) data_section) & 0xFFFF); response.available_bytes = (word)r; } srv_cmd_fill_rap_response (pCtx->tmpBuffer, pCtx->tmpBuffer, original_size_left, pOutHdr, &response); return r; }
/* Offset of first EIF_INTEGER_64. */ rt_public size_t eif_i64off(size_t nb_ref, size_t nb_char, size_t nb_int16, size_t nb_int32, size_t nb_r32, size_t nb_ptr) { size_t to_add = eif_ptroff(nb_ref,nb_char, nb_int16,nb_int32,nb_r32) + PTRACS(nb_ptr); return to_add + PADD(to_add, I64SIZ); }
/* Offset of first EIF_REAL_32. */ rt_public size_t eif_r32off(size_t nb_ref, size_t nb_char, size_t nb_int16, size_t nb_int32) { size_t to_add = eif_lngoff(nb_ref,nb_char, nb_int16) + LNGACS(nb_int32); return to_add + PADD(to_add, R32SIZ); }
/* ================ int length - x PFBYTE pOutBuf - x PSMB_TRANSACTIONRS pOutTran - x ================ */ int NetShareEnum (PSMB_SESSIONCTX pCtx, PRTSMB_RAP_REQUEST pFunc, PRTSMB_HEADER pInHdr, PFVOID pInBuf, PRTSMB_HEADER pOutHdr, rtsmb_size size_left, PFWORD param_size) { PSR_RESOURCE pOutRes; RTSMB_RAP_GET_INFO command; RTSMB_RAP_ENUM_HEADER_R header; RTSMB_RAP_SHARE_ENUM_INFO_R info; PFVOID data_section; PFVOID pOutBuf = pCtx->tmpBuffer; int r, i; r = srv_cmd_read_rap_get_info (pCtx->write_origin, pInBuf, pCtx->current_body_size - (rtsmb_size)(PDIFF (pInBuf, pCtx->read_origin)), pInHdr, &command); if (r == -1) return -1; size_left = MIN (command.receive_size, size_left); // Fill out parameters header.status = RAP_ERROR_ACCESS_DENIED; header.converter = 0; header.entry_count = 0; header.available_entries = 0; r = srv_cmd_fill_rap_share_enum_header (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &header); if (r == -1) return r; size_left -= (rtsmb_size)r; *param_size = (word) r; pOutBuf = PADD (pCtx->tmpBuffer, r); data_section = pOutBuf; CLAIM_SHARE (); header.entry_count = 0; header.available_entries = 0; info.total_shares = 0; // find out how many shares there are. for(pOutRes = SR_FirstResource(); pOutRes != (PSR_RESOURCE)0; pOutRes = SR_NextResource(pOutRes)) { info.total_shares++; } // pack each share into the buffer. i = 0; r = 0; for(pOutRes = SR_FirstResource(); pOutRes != (PSR_RESOURCE)0; pOutRes = SR_NextResource(pOutRes)) { int this_r; info.share_num = info.total_shares - (i++) - 1; rtsmb_cpy (info.share_data.name, pOutRes->name); info.share_data.type = pOutRes->stype; info.share_data.comment = pOutRes->comment; header.entry_count++; header.available_entries++; this_r = srv_cmd_fill_rap_share_enum_info (pCtx->tmpBuffer, pOutBuf, size_left, pOutHdr, &info); if (this_r == -1) break; r += this_r; } RELEASE_SHARE (); if (r == -1) { header.status = RAP_NERR_BUFTOOSMALL; header.converter = 0; r = 0; } else { header.status = RAP_NERR_SUCCESS; header.converter = (word)(((int) data_section) & 0xFFFF); } srv_cmd_fill_rap_share_enum_header (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &header); return r; } // End NetShareEnum
static XC_ALLOCATOR_MALLOC(xc_allocator_bestfit_malloc) /* {{{ */ { xc_allocator_bestfit_block_t *prev, *cur; xc_allocator_bestfit_block_t *newb, *b; xc_memsize_t realsize; xc_memsize_t minsize; void *p; /* [xc_allocator_bestfit_block_t:size|size] */ realsize = BLOCK_HEADER_SIZE() + size; /* realsize is ALIGNed so next block start at ALIGNed address */ realsize = ALIGN(realsize); TRACE("avail: %lu (%luKB). Allocate size: %lu realsize: %lu (%luKB)" , allocator->avail, allocator->avail / 1024 , size , realsize, realsize / 1024 ); do { p = NULL; if (allocator->avail < realsize) { TRACE("%s", " oom"); break; } b = NULL; minsize = ULONG_MAX; /* prev|cur */ for (prev = allocator->headblock; prev->next; prev = cur) { /* while (prev->next != 0) { */ cur = prev->next; xc_block_check(cur); if (cur->size == realsize) { /* found a perfect fit, stop searching */ b = prev; break; } /* make sure we can split on the block */ else if (cur->size > (sizeof(xc_allocator_bestfit_block_t) + realsize) && cur->size < minsize) { /* cur is acceptable and memller */ b = prev; minsize = cur->size; } prev = cur; } if (b == NULL) { TRACE("%s", " no fit chunk"); break; } prev = b; cur = prev->next; p = PADD(cur, BLOCK_HEADER_SIZE()); /* update the block header */ allocator->avail -= realsize; /* perfect fit, just unlink */ if (cur->size == realsize) { prev->next = cur->next; TRACE(" perfect fit. Got: %p", p); break; } /* make new free block after alloced space */ /* save, as it might be overwrited by newb (cur->size is ok) */ b = cur->next; /* prev|cur |next=b */ newb = (xc_allocator_bestfit_block_t *)PADD(cur, realsize); xc_block_setup(newb, cur->size - realsize, b); cur->size = realsize; /* prev|cur|newb|next * `--^ */ TRACE(" -> avail: %lu (%luKB). new next: %p offset: %lu %luKB. Got: %p" , allocator->avail, allocator->avail / 1024 , (void *) newb , PSUB(newb, allocator), PSUB(newb, allocator) / 1024 , p ); prev->next = newb; /* prev|cur|newb|next * `-----^ */ } while (0); return p; }
static int open_aiff(bgav_demuxer_context_t * ctx) { chunk_header_t ch; comm_chunk_t comm; uint32_t fourcc; bgav_stream_t * s = NULL; aiff_priv_t * priv; int keep_going = 1; bgav_track_t * track; char * tmp_string; /* Create track */ ctx->tt = bgav_track_table_create(1); track = ctx->tt->cur; /* Check file magic */ if(!read_chunk_header(ctx->input, &ch) || (ch.fourcc != BGAV_MK_FOURCC('F','O','R','M'))) return 0; if(!bgav_input_read_fourcc(ctx->input, &fourcc)) return 0; /* Allocate private struct */ priv = calloc(1, sizeof(*priv)); ctx->priv = priv; if(fourcc == BGAV_MK_FOURCC('A','I','F','C')) { priv->is_aifc = 1; } else if(fourcc != BGAV_MK_FOURCC('A','I','F','F')) { return 0; } /* Read chunks until we are done */ while(keep_going) { if(!read_chunk_header(ctx->input, &ch)) return 0; switch(ch.fourcc) { case BGAV_MK_FOURCC('C','O','M','M'): s = bgav_track_add_audio_stream(track, ctx->opt); memset(&comm, 0, sizeof(comm)); if(!comm_chunk_read(&ch, ctx->input, &comm, priv->is_aifc)) { return 0; } s->data.audio.format.samplerate = comm.samplerate; s->data.audio.format.num_channels = comm.num_channels; s->data.audio.bits_per_sample = comm.num_bits; /* * Multichannel support according to * http://music.calarts.edu/~tre/AIFFC/ */ switch(s->data.audio.format.num_channels) { case 1: s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_CENTER; break; case 2: s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT; s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_RIGHT; break; case 3: s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT; s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_CENTER; s->data.audio.format.channel_locations[2] = GAVL_CHID_FRONT_RIGHT; break; case 4: /* Note: 4 channels can also be "left center right surround" but we believe, that quad is more common */ s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT; s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_RIGHT; s->data.audio.format.channel_locations[2] = GAVL_CHID_REAR_LEFT; s->data.audio.format.channel_locations[3] = GAVL_CHID_REAR_RIGHT; break; case 6: s->data.audio.format.channel_locations[0] = GAVL_CHID_FRONT_LEFT; s->data.audio.format.channel_locations[1] = GAVL_CHID_FRONT_CENTER_LEFT; s->data.audio.format.channel_locations[2] = GAVL_CHID_FRONT_CENTER; s->data.audio.format.channel_locations[3] = GAVL_CHID_FRONT_RIGHT; s->data.audio.format.channel_locations[4] = GAVL_CHID_FRONT_CENTER_RIGHT; s->data.audio.format.channel_locations[5] = GAVL_CHID_REAR_CENTER; break; } if(!priv->is_aifc) s->fourcc = BGAV_MK_FOURCC('a','i','f','f'); else if(comm.compression_type == BGAV_MK_FOURCC('N','O','N','E')) s->fourcc = BGAV_MK_FOURCC('a','i','f','f'); else s->fourcc = comm.compression_type; switch(s->fourcc) { case BGAV_MK_FOURCC('a','i','f','f'): if(s->data.audio.bits_per_sample <= 8) { s->data.audio.block_align = comm.num_channels; } else if(s->data.audio.bits_per_sample <= 16) { s->data.audio.block_align = 2 * comm.num_channels; } else if(s->data.audio.bits_per_sample <= 24) { s->data.audio.block_align = 3 * comm.num_channels; } else if(s->data.audio.bits_per_sample <= 32) { s->data.audio.block_align = 4 * comm.num_channels; } else { bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "%d bit aiff not supported", s->data.audio.bits_per_sample); return 0; } s->data.audio.format.samples_per_frame = 1024; priv->samples_per_block = 1; break; case BGAV_MK_FOURCC('f','l','3','2'): s->data.audio.block_align = 4 * comm.num_channels; priv->samples_per_block = 1; break; case BGAV_MK_FOURCC('f','l','6','4'): s->data.audio.block_align = 8 * comm.num_channels; priv->samples_per_block = 1; s->data.audio.format.samples_per_frame = 1024; break; case BGAV_MK_FOURCC('a','l','a','w'): case BGAV_MK_FOURCC('A','L','A','W'): case BGAV_MK_FOURCC('u','l','a','w'): case BGAV_MK_FOURCC('U','L','A','W'): s->data.audio.block_align = comm.num_channels; priv->samples_per_block = 1; s->data.audio.format.samples_per_frame = 1024; break; #if 0 case BGAV_MK_FOURCC('G','S','M',' '): s->data.audio.block_align = 33; priv->samples_per_block = 160; s->data.audio.format.samples_per_frame = 160; break; #endif case BGAV_MK_FOURCC('M','A','C','3'): s->data.audio.block_align = comm.num_channels * 2; priv->samples_per_block = 6; s->data.audio.format.samples_per_frame = 6*128; break; case BGAV_MK_FOURCC('M','A','C','6'): s->data.audio.block_align = comm.num_channels; priv->samples_per_block = 6; s->data.audio.format.samples_per_frame = 6*128; break; default: bgav_log(s->opt, BGAV_LOG_ERROR, LOG_DOMAIN, "Compression %c%c%c%c not supported", comm.compression_type >> 24, (comm.compression_type >> 16) & 0xff, (comm.compression_type >> 8) & 0xff, (comm.compression_type) & 0xff); return 0; } break; case BGAV_MK_FOURCC('N','A','M','E'): tmp_string = read_meta_string(ctx->input, &ch); gavl_metadata_set_nocpy(&ctx->tt->cur->metadata, GAVL_META_TITLE, tmp_string); break; case BGAV_MK_FOURCC('A','U','T','H'): tmp_string = read_meta_string(ctx->input, &ch); gavl_metadata_set_nocpy(&ctx->tt->cur->metadata, GAVL_META_AUTHOR, tmp_string); break; case BGAV_MK_FOURCC('(','c',')',' '): tmp_string = read_meta_string(ctx->input, &ch); gavl_metadata_set_nocpy(&ctx->tt->cur->metadata, GAVL_META_COPYRIGHT, tmp_string); break; case BGAV_MK_FOURCC('A','N','N','O'): tmp_string = read_meta_string(ctx->input, &ch); gavl_metadata_set_nocpy(&ctx->tt->cur->metadata, GAVL_META_COMMENT, tmp_string); break; case BGAV_MK_FOURCC('S','S','N','D'): bgav_input_skip(ctx->input, 4); /* Offset */ bgav_input_skip(ctx->input, 4); /* Blocksize */ ctx->data_start = ctx->input->position; ctx->flags |= BGAV_DEMUXER_HAS_DATA_START; priv->data_size = ch.size - 8; ctx->tt->cur->audio_streams->duration = pos_2_time(ctx, priv->data_size + ctx->data_start); track->duration = gavl_time_unscale(s->data.audio.format.samplerate, ctx->tt->cur->audio_streams->duration); keep_going = 0; break; default: bgav_input_skip(ctx->input, PADD(ch.size)); break; } } if(ctx->input->input->seek_byte) ctx->flags |= BGAV_DEMUXER_CAN_SEEK; if(priv->is_aifc) gavl_metadata_set(&ctx->tt->cur->metadata, GAVL_META_FORMAT, "AIFF-C"); else gavl_metadata_set(&ctx->tt->cur->metadata, GAVL_META_FORMAT, "AIFF"); ctx->index_mode = INDEX_MODE_PCM; return 1; }
/* Offset of first EIF_INTEGER_16. */ rt_public size_t eif_i16off(size_t nb_ref, size_t nb_char) { size_t to_add = eif_chroff(nb_ref) + CHRACS(nb_char); return to_add + PADD(to_add, I16SIZ); }
/* Offset of first EIF_INTEGER_32. */ rt_public size_t eif_lngoff(size_t nb_ref, size_t nb_char, size_t nb_int16) { size_t to_add = eif_i16off(nb_ref, nb_char) + I16ACS(nb_int16); return to_add + PADD(to_add, LNGSIZ); }
/* ================ ================ */ int NetServerEnum2 (PSMB_SESSIONCTX pCtx, PRTSMB_RAP_REQUEST pFunc, PRTSMB_HEADER pInHdr, PFVOID pInBuf, PRTSMB_HEADER pOutHdr, rtsmb_size size_left, PFWORD param_size) { RTSMB_RAP_SERVER_ENUM2 command; RTSMB_RAP_ENUM_HEADER_R header; RTSMB_RAP_SERVER_INFO_1 info; PRTSMB_BROWSE_SERVER_INFO plist; PFVOID data_section; PFVOID pOutBuf = pCtx->tmpBuffer; int r, i, j, max_possible; rtsmb_char domain [RTSMB_NB_NAME_SIZE + 1]; command.domain = domain; command.domain_size = RTSMB_NB_NAME_SIZE; r = srv_cmd_read_rap_server_enum2 (pCtx->write_origin, pInBuf, pCtx->current_body_size - (rtsmb_size)(PDIFF (pInBuf, pCtx->read_origin)), pInHdr, &command); if (r == -1) return -1; size_left = MIN (command.receive_size, size_left); // Fill out parameters header.status = RAP_ERROR_ACCESS_DENIED; header.converter = 0; header.entry_count = 0; header.available_entries = 0; r = srv_cmd_fill_rap_share_enum_header (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &header); if (r == -1) return r; size_left -= (rtsmb_size)r; *param_size = (word)r; pOutBuf = PADD (pCtx->tmpBuffer, r); data_section = pOutBuf; rtp_sig_mutex_claim((RTP_MUTEX) prtsmb_browse_ctx->mutex); header.entry_count = 0; header.available_entries = 0; info.info_total = 0; if (pCtx->state == BROWSE_FAIL) { /* domain is invalid. tell client */ header.status = RAP_NERR_INVALID_DOMAIN; srv_cmd_fill_rap_share_enum_header (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &header); return r; } else if (pCtx->state == BROWSE_FINISH) { /* we have previously been here and punted our netenum2 to another server. here, we have the data now and we want to ship it out. */ plist = prtsmb_srv_ctx->enum_results; max_possible = prtsmb_srv_ctx->enum_results_size; } /* is this a domain enum or server enum? */ else if (command.server_type == SV_TYPE_DOMAIN_ENUM) { plist = prtsmb_srv_ctx->domain_table; max_possible = prtsmb_srv_ctx->domain_table_size; } else { char group_name [RTSMB_NB_NAME_SIZE + 1]; plist = prtsmb_srv_ctx->server_table; max_possible = prtsmb_srv_ctx->server_table_size; rtsmb_util_rtsmb_to_ascii (command.domain, group_name, CFG_RTSMB_USER_CODEPAGE); /* if the group name is null or the same as our group, we just get it from our own list. else, we need to outsource the netenum2 */ if (group_name[0] && rtsmb_strcasecmp (group_name, rtsmb_srv_nbns_get_our_group (), CFG_RTSMB_USER_CODEPAGE) != 0) { rtp_sig_mutex_release((RTP_MUTEX) prtsmb_browse_ctx->mutex); /* we have a server enum request outside of our own workgroup. */ /* punt it off to the browse layer, which will come up with something to hand over */ pCtx->state = BROWSE_MUTEX; pCtx->server_enum_type = command.server_type; tc_strcpy (pCtx->server_enum_domain, group_name); rtsmb_srv_browse_finish_server_enum (pCtx); return -2; /* tell upper layers to not send response yet */ } } // find out how many servers there are. for (i = 0; i < max_possible; i++) { if (plist[i].type & command.server_type) { info.info_total++; } } // pack each server into the buffer. for (i = 0, j = 0, r = 0; i < max_possible; i++) { int this_r; rtsmb_char comment [RTSMB_MAX_COMMENT_SIZE + 1]; /* take care of non-used types (0-value 'type') and servers we aren't interested in */ if ((plist[i].type & command.server_type) == 0) { continue; } info.info_num = info.info_total - (j++) - 1; rtsmb_util_ascii_to_rtsmb (plist[i].name, info.name, CFG_RTSMB_USER_CODEPAGE); info.type = plist[i].type; rtsmb_util_ascii_to_rtsmb (plist[i].comment, comment, CFG_RTSMB_USER_CODEPAGE); info.comment = comment; info.version_minor = plist[i].version_minor; info.version_major = plist[i].version_major; header.entry_count++; header.available_entries++; if (command.information_level == 0) { this_r = srv_cmd_fill_rap_server_enum_info_0 (pCtx->tmpBuffer, pOutBuf, size_left, pOutHdr, &info); } else /* must be one... */ { this_r = srv_cmd_fill_rap_server_enum_info_1 (pCtx->tmpBuffer, pOutBuf, size_left, pOutHdr, &info); } if (this_r == -1) break; r += this_r; } rtp_sig_mutex_release((RTP_MUTEX) prtsmb_browse_ctx->mutex); if (r == -1) { header.status = RAP_NERR_BUFTOOSMALL; header.converter = 0; r = 0; } else { header.status = RAP_NERR_SUCCESS; header.converter = (word)(((int) data_section) & 0xFFFF); } srv_cmd_fill_rap_share_enum_header (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &header); return r; }
/* Offset of first EIF_POINTER. */ rt_public size_t eif_ptroff(size_t nb_ref, size_t nb_char, size_t nb_int16, size_t nb_int32, size_t nb_r32) { size_t to_add = eif_r32off(nb_ref,nb_char, nb_int16,nb_int32) + R32ACS(nb_r32); return to_add + PADD(to_add, PTRSIZ); }
/* ================ int level - x int length - x PFBYTE pOutBuf - x PSMB_TRANSACTIONRS pOutTran - x ================ */ int NetServerGetInfo(PSMB_SESSIONCTX pCtx, PRTSMB_RAP_REQUEST pFunc, PRTSMB_HEADER pInHdr, PFVOID pInBuf, PRTSMB_HEADER pOutHdr, rtsmb_size size_left, PFWORD param_size) { RTSMB_RAP_GET_INFO command; RTSMB_RAP_RESPONSE response; RTSMB_RAP_SERVER_INFO_1 info; rtsmb_char comment [RTSMB_MAX_COMMENT_SIZE + 1]; PFVOID data_section; PFVOID pOutBuf = pCtx->tmpBuffer; int r; r = srv_cmd_read_rap_get_info (pCtx->write_origin, pInBuf, pCtx->current_body_size - (rtsmb_size)PDIFF (pInBuf, pCtx->read_origin), pInHdr, &command); if (r == -1) return -1; size_left = MIN (command.receive_size, size_left); // Fill out parameters response.status = RAP_ERROR_ACCESS_DENIED; response.converter = 0; response.available_bytes = 0; r = srv_cmd_fill_rap_response (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &response); if (r == -1) return r; size_left -= (rtsmb_size)r; *param_size = (word)r; pOutBuf = PADD (pCtx->tmpBuffer, r); data_section = pOutBuf; rtsmb_util_ascii_to_rtsmb (rtsmb_srv_nbns_get_our_name (), info.name, CFG_RTSMB_USER_CODEPAGE); rtsmb_util_ascii_to_rtsmb (CFG_RTSMB_DEFAULT_COMMENT, comment, CFG_RTSMB_USER_CODEPAGE); info.version_major = 4; info.version_minor = 0; info.type = rtsmb_srv_browse_get_server_type (); info.comment = comment; switch (command.information_level) { case 0: { r = srv_cmd_fill_rap_server_info_0 (pCtx->write_origin, pOutBuf, size_left, pOutHdr, &info); } break; case 1: { r = srv_cmd_fill_rap_server_info_1 (pCtx->write_origin, pOutBuf, size_left, pOutHdr, &info); } break; } if (r == -1) { response.status = RAP_NERR_BUFTOOSMALL; response.converter = 0; r = 0; } else { response.status = RAP_NERR_SUCCESS; response.converter = (word)(((int) data_section) & 0xFFFF); } response.available_bytes = (word) r; srv_cmd_fill_rap_response (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &response); return r; }
/* Offset of first EIF_REAL_64. */ rt_public size_t eif_r64off(size_t nb_ref, size_t nb_char, size_t nb_int16, size_t nb_int32, size_t nb_r32, size_t nb_ptr, size_t nb_int64) { size_t to_add = eif_i64off(nb_ref,nb_char, nb_int16,nb_int32,nb_r32, nb_ptr) + I64ACS(nb_int64); return to_add + PADD(to_add, R64SIZ); }
/* ================ int level - x int length - x PFBYTE pOutBuf - x PSMB_TRANSACTIONRS pOutTran - x ================ */ int NetWkstaGetInfo (PSMB_SESSIONCTX pCtx, PRTSMB_RAP_REQUEST pFunc, PRTSMB_HEADER pInHdr, PFVOID pInBuf, PRTSMB_HEADER pOutHdr, rtsmb_size size_left, PFWORD param_size) { RTSMB_RAP_GET_INFO command; RTSMB_RAP_WKSTA_INFO info; RTSMB_RAP_RESPONSE response; PFVOID pOutBuf = pCtx->tmpBuffer; PFVOID data_section; rtsmb_char group_name [RTSMB_NB_NAME_SIZE + 1]; rtsmb_char comp_name [RTSMB_NB_NAME_SIZE + 1]; int r; r = srv_cmd_read_rap_get_info (pCtx->write_origin, pInBuf, pCtx->current_body_size - (rtsmb_size)(PDIFF (pInBuf, pCtx->read_origin)), pInHdr, &command); if (r == -1) return -1; size_left = MIN (command.receive_size, size_left); // Fill out parameters response.status = RAP_ERROR_ACCESS_DENIED; response.converter = 0; response.available_bytes = 0; r = srv_cmd_fill_rap_response (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &response); if (r == -1) return r; size_left -= (rtsmb_size)r; *param_size = (word)r; pOutBuf = PADD (pCtx->tmpBuffer, r); data_section = pOutBuf; rtsmb_util_ascii_to_rtsmb (rtsmb_srv_nbns_get_our_group (), group_name, CFG_RTSMB_USER_CODEPAGE); rtsmb_util_ascii_to_rtsmb (rtsmb_srv_nbns_get_our_name (), comp_name, CFG_RTSMB_USER_CODEPAGE); info.version_minor = 0; info.version_major = 4; info.computer_name = comp_name; info.username = (PFRTCHAR)0; info.lan_group = group_name; info.logon_domain = group_name; info.other_domains = (PFRTCHAR)0; r = srv_cmd_fill_rap_wksta_info (pCtx->tmpBuffer, pOutBuf, size_left, pOutHdr, &info); if (r == -1) { response.status = RAP_NERR_BUFTOOSMALL; response.converter = 0; response.available_bytes = (word) srv_cmd_sizeof_rap_wksta_info (pOutHdr, &info); r = 0; } else { response.status = RAP_NERR_SUCCESS; response.converter = (word)(((int) data_section) & 0xFFFF); response.available_bytes = (word)r; } response.available_bytes = (word)r; srv_cmd_fill_rap_response (pCtx->tmpBuffer, pCtx->tmpBuffer, size_left, pOutHdr, &response); return r; } // End NetWkstaGetInfo