Пример #1
0
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;
}
Пример #2
0
/* }}} */
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;
}
Пример #3
0
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);
        }
    }
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
/**
 * 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;
}
Пример #7
0
/* 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);
}
Пример #8
0
/*
================

    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, &param_size);
        break;
    case RAP_COM_NET_SERVER_GETINFO:
        data_size = NetServerGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr,
            size_left, &param_size);
        break;
    case RAP_COM_NET_WKSTA_GETINFO:
        data_size = NetWkstaGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr,
            size_left, &param_size);
        break;
    case RAP_COM_NET_SHARE_GETINFO:
        data_size = NetShareGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr,
            size_left, &param_size);
        break;
    case RAP_COM_WPRINTQ_GETINFO:
        data_size = WPrintQGetInfo (pCtx, &func, pInHdr, pInBuf, pOutHdr,
            size_left, &param_size);
        break;
    case RAP_COM_NET_SERVER_ENUM2:
        data_size = NetServerEnum2 (pCtx, &func, pInHdr, pInBuf, pOutHdr,
            size_left, &param_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
Пример #9
0
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
Пример #10
0
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;
}
Пример #11
0
/* 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);
}
Пример #12
0
/* 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);
}
Пример #13
0
/*
================
    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
Пример #14
0
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;
}
Пример #15
0
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;
  }
Пример #16
0
/* 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);
}
Пример #17
0
/* 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);
}
Пример #18
0
/*
================

================
*/
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;
}
Пример #19
0
/* 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);
}
Пример #20
0
/*
================
    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;
}
Пример #21
0
/* 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);
}
Пример #22
0
/*
================

    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