Example #1
0
Boolean PrimesTable::TableBuffer::RetrieveBlock(Ulong Index_, long Offset_, fstream& Fin_)
{
  Ulong BlockNum_ = Index_ / PrimesTable::TABLESIZE;

  Fin_.seekg(0, ios::end);
  Fin_.clear();

  long StartPos_ = BlockNum_ * TABLESIZE * sizeof(long);
  long Fsize_ = Fin_.tellg();
  Fsize_ -= Offset_;

  if (StartPos_ < Fsize_)    
    if (Fin_.seekg(StartPos_ + Offset_).good())
    {
      Fin_.read((char*)_Table, TABLESIZE * sizeof(long));

      size_t i;
      long BufSize_ = TABLESIZE;

      for (i = TABLESIZE - 1; i != size_t(-1); --i)
        if (!_Table[i])
          --BufSize_;
        else
          break;

      if (BufSize_)
      {
        StartPos_ /= sizeof(long);
        SetLimit(StartPos_, BufSize_);
        return Fin_.good();
      }
    }

  return FALSE;
}
Example #2
0
	KMyCanvas()
	{
		m_x			 = (double) - 2.1;
		m_y			 = (double) - 1.375;
		m_unit		 = (double) 1.0 / 256;
		m_lastwidth  = 0;
		m_lastheight = 0;
				
		memset(Buffer, 0, sizeof(Buffer));
		SetSize((int) (3 * 256), (int) (2.75 * 256), 24, 24);
		SetLimit(32, FALSE);
	}
Example #3
0
void WPJGC::CheckMemoryLeak()
{
	SetLimit(false);
	GC();

	U_INT leakSize = 0;
	U_INT poolSize = 0;

	foreach_in_list_auto(WPJObject*, itor, m_GCList)
	{
		if (ptr_data(itor)->GetbInPool())
			poolSize += ptr_data(itor)->GetSize();
		else
			leakSize += ptr_data(itor)->GetSize();

		WPJLOG("MemoryLeak ... %u Bytes\n", ptr_data(itor)->GetSize());
	}

	WPJLOG("MemoryLeak Total is ... %u Bytes\n", leakSize);
	WPJLOG("MemoryPool Total is ... %u Bytes\n", poolSize);
	SetLimit(true);

}
Example #4
0
void CChannel::SetModes ( unsigned long ulModes, const std::vector < CString >& vecModeParams )
{
    unsigned int uiParamIndex = 0;
    m_ulModes = ulModes;

    // Ojo con el órden límite - clave
    // El ircu nos manda siempre antes el límite que
    // la clave en el caso de que ambos estén presentes.
    // Esto es ligeramente chapucero, pero funciona.
    if ( m_ulModes & CMODE_LIMIT )
    {
        SetLimit ( atoi ( vecModeParams [ uiParamIndex ] ) );
        ++uiParamIndex;
    }
    if ( m_ulModes & CMODE_KEY )
    {
        SetKey ( vecModeParams [ uiParamIndex ] );
        ++uiParamIndex;
    }
}
Example #5
0
BOOL KMyCanvas::OnCommand(WPARAM wParam, LPARAM lParam)
{
	switch ( LOWORD(wParam) )
	{
		case ID_VIEW_RESET:
			m_x = -2; m_y = -1; m_unit = (double) 0.0025;
			InvalidateRect(m_hWnd, NULL, TRUE);
			return TRUE;

		case  IDM_OPT_64 : SetLimit(   64, TRUE); return TRUE;
		case  IDM_OPT_128: SetLimit(  128, TRUE); return TRUE;
		case  IDM_OPT_256: SetLimit(  256, TRUE); return TRUE;
		case  IDM_OPT_512: SetLimit(  512, TRUE); return TRUE;
		case IDM_OPT_1024: SetLimit( 1024, TRUE); return TRUE;
		case IDM_OPT_4096: SetLimit( 2048, TRUE); return TRUE;
 	   case IDM_OPT_16384: SetLimit(16384, TRUE); return TRUE;
	}

	return FALSE;
}
Example #6
0
void BipedDef::DisableLimit()
{
	SetLimit(false);
}
Example #7
0
void BipedDef::EnableLimit()
{
	SetLimit(true);
}
Example #8
0
NTSTATUS FdoPortIoCtl(
    IN PC0C_FDOPORT_EXTENSION pDevExt,
    IN PIRP pIrp)
{
    NTSTATUS status;
    PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
    ULONG code = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
    KIRQL oldIrql;
    PC0C_IO_PORT pIoPortLocal;

    pIrp->IoStatus.Information = 0;
    pIoPortLocal = pDevExt->pIoPortLocal;

    if ((pIoPortLocal->handFlow.ControlHandShake & SERIAL_ERROR_ABORT) &&
            pIoPortLocal->errors && code != IOCTL_SERIAL_GET_COMMSTATUS)
    {
        status = STATUS_CANCELLED;
    } else {
        status = STATUS_SUCCESS;

        switch (code) {
        case IOCTL_SERIAL_SET_RTS:
        case IOCTL_SERIAL_CLR_RTS:
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            switch (pIoPortLocal->handFlow.FlowReplace & SERIAL_RTS_MASK) {
            case SERIAL_RTS_HANDSHAKE:
            case SERIAL_TRANSMIT_TOGGLE:
                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                status = STATUS_INVALID_PARAMETER;
                break;
            default: {
                LIST_ENTRY queueToComplete;

                InitializeListHead(&queueToComplete);

                SetModemControl(
                    pIoPortLocal,
                    code == IOCTL_SERIAL_SET_RTS ? C0C_MCR_RTS : 0,
                    C0C_MCR_RTS,
                    &queueToComplete);

                if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                    ReadWrite(
                        pIoPortLocal, FALSE,
                        pIoPortLocal->pIoPortRemote, FALSE,
                        &queueToComplete);
                }

                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                FdoPortCompleteQueue(&queueToComplete);
            }
            }
            break;
        case IOCTL_SERIAL_SET_DTR:
        case IOCTL_SERIAL_CLR_DTR:
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            switch (pIoPortLocal->handFlow.ControlHandShake & SERIAL_DTR_MASK) {
            case SERIAL_DTR_HANDSHAKE:
                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                status = STATUS_INVALID_PARAMETER;
                break;
            default: {
                LIST_ENTRY queueToComplete;

                InitializeListHead(&queueToComplete);

                SetModemControl(
                    pIoPortLocal,
                    code == IOCTL_SERIAL_SET_DTR ? C0C_MCR_DTR : 0,
                    C0C_MCR_DTR,
                    &queueToComplete);

                if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                    ReadWrite(
                        pIoPortLocal, FALSE,
                        pIoPortLocal->pIoPortRemote, FALSE,
                        &queueToComplete);
                }

                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                FdoPortCompleteQueue(&queueToComplete);
            }
            }
            break;
        case IOCTL_SERIAL_SET_MODEM_CONTROL: {
            LIST_ENTRY queueToComplete;
            UCHAR mask;
            PUCHAR pSysBuf;
            ULONG InputBufferLength;

            InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

            if (InputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;

            if (InputBufferLength >= (sizeof(ULONG) + sizeof(ULONG) + C0CE_SIGNATURE_SIZE) &&
                    RtlEqualMemory(pSysBuf + sizeof(ULONG) + sizeof(ULONG), C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE))
            {
                mask = C0C_MCR_MASK & (UCHAR)*((PULONG)pSysBuf + 1);
            } else {
                mask = C0C_MCR_MASK;
            }

            InitializeListHead(&queueToComplete);

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            SetModemControl(pIoPortLocal, (UCHAR)*(PULONG)pSysBuf, mask, &queueToComplete);

            if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                ReadWrite(
                    pIoPortLocal, FALSE,
                    pIoPortLocal->pIoPortRemote, FALSE,
                    &queueToComplete);
            }

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_GET_MODEM_CONTROL:
        case IOCTL_SERIAL_GET_DTRRTS: {
            ULONG modemControl;
            PUCHAR pSysBuf;
            ULONG OutputBufferLength;

            OutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

            if (OutputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            modemControl = pIoPortLocal->modemControl;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);

            pSysBuf = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;

            if (code == IOCTL_SERIAL_GET_DTRRTS) {
                modemControl &= SERIAL_DTR_STATE | SERIAL_RTS_STATE;
                pIrp->IoStatus.Information = sizeof(ULONG);
            } else {
                ULONG InputBufferLength;

                InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

                if (OutputBufferLength >= (sizeof(ULONG) + C0CE_SIGNATURE_SIZE) &&
                        InputBufferLength >= C0CE_SIGNATURE_SIZE &&
                        RtlEqualMemory(pSysBuf, C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE))
                {
                    RtlCopyMemory(pSysBuf + sizeof(PULONG), C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE);

                    if (OutputBufferLength > (sizeof(ULONG) + C0CE_SIGNATURE_SIZE)) {
                        RtlZeroMemory(pSysBuf + sizeof(ULONG) + C0CE_SIGNATURE_SIZE,
                                      OutputBufferLength - (sizeof(ULONG) + C0CE_SIGNATURE_SIZE));
                    }

                    pIrp->IoStatus.Information = OutputBufferLength;
                } else {
                    pIrp->IoStatus.Information = sizeof(ULONG);
                }

                modemControl &= C0C_MCR_MASK;
            }

            *(PULONG)pSysBuf = modemControl;

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        }
        case IOCTL_SERIAL_SET_XON: {
            LIST_ENTRY queueToComplete;

            InitializeListHead(&queueToComplete);

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            SetXonXoffHolding(pIoPortLocal, C0C_XCHAR_ON);

            if (pIoPortLocal->tryWrite) {
                ReadWrite(
                    pIoPortLocal, FALSE,
                    pIoPortLocal->pIoPortRemote, FALSE,
                    &queueToComplete);
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_SET_XOFF:
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            SetXonXoffHolding(pIoPortLocal, C0C_XCHAR_OFF);
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        case IOCTL_SERIAL_SET_BREAK_ON: {
            LIST_ENTRY queueToComplete;

            InitializeListHead(&queueToComplete);

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            SetBreakHolding(pIoPortLocal, TRUE, &queueToComplete);
            UpdateTransmitToggle(pIoPortLocal, &queueToComplete);

            ReadWrite(
                pIoPortLocal, FALSE,
                pIoPortLocal->pIoPortRemote, FALSE,
                &queueToComplete);

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_SET_BREAK_OFF: {
            LIST_ENTRY queueToComplete;

            InitializeListHead(&queueToComplete);

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            SetBreakHolding(pIoPortLocal, FALSE, &queueToComplete);
            UpdateTransmitToggle(pIoPortLocal, &queueToComplete);

            if (pIoPortLocal->tryWrite || pIoPortLocal->pIoPortRemote->tryWrite) {
                ReadWrite(
                    pIoPortLocal, FALSE,
                    pIoPortLocal->pIoPortRemote, FALSE,
                    &queueToComplete);
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_GET_MODEMSTATUS:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PULONG)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->modemStatus;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(ULONG);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_SET_WAIT_MASK:
            status = FdoPortSetWaitMask(pIoPortLocal, pIrp, pIrpStack);
            break;
        case IOCTL_SERIAL_GET_WAIT_MASK:
            status = FdoPortGetWaitMask(pIoPortLocal, pIrp, pIrpStack);
            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_WAIT_ON_MASK:
            status = FdoPortWaitOnMask(pIoPortLocal, pIrp, pIrpStack);
#if ENABLE_TRACING
            if (status == STATUS_SUCCESS)
                TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
#endif /* ENABLE_TRACING */
            break;
        case IOCTL_SERIAL_IMMEDIATE_CHAR:
            status = FdoPortImmediateChar(pIoPortLocal, pIrp, pIrpStack);
            break;
        case IOCTL_SERIAL_XOFF_COUNTER:
            status = FdoPortXoffCounter(pIoPortLocal, pIrp, pIrpStack);
            break;
        case IOCTL_SERIAL_PURGE: {
            LIST_ENTRY queueToComplete;
            PULONG pSysBuf;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PULONG)pIrp->AssociatedIrp.SystemBuffer;

            if (*pSysBuf & ~(
                        SERIAL_PURGE_TXABORT |
                        SERIAL_PURGE_RXABORT |
                        SERIAL_PURGE_TXCLEAR |
                        SERIAL_PURGE_RXCLEAR
                    )) {
                status = STATUS_INVALID_PARAMETER;
                break;
            }

            InitializeListHead(&queueToComplete);
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            if (*pSysBuf & SERIAL_PURGE_RXABORT)
                CancelQueue(&pIoPortLocal->irpQueues[C0C_QUEUE_READ], &queueToComplete);

            if (*pSysBuf & SERIAL_PURGE_TXABORT)
                CancelQueue(&pIoPortLocal->irpQueues[C0C_QUEUE_WRITE], &queueToComplete);

            if (*pSysBuf & SERIAL_PURGE_RXCLEAR) {
                PurgeBuffer(&pIoPortLocal->readBuf);
                UpdateHandFlow(pIoPortLocal, TRUE, &queueToComplete);
                if (pIoPortLocal->tryWrite || pIoPortLocal->pIoPortRemote->tryWrite) {
                    ReadWrite(
                        pIoPortLocal, FALSE,
                        pIoPortLocal->pIoPortRemote, FALSE,
                        &queueToComplete);
                }
            }

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);

            break;
        }
        case IOCTL_SERIAL_GET_COMMSTATUS: {
            PSERIAL_STATUS pSysBuf;
            PIRP pIrpWrite;

            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_STATUS)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PSERIAL_STATUS)pIrp->AssociatedIrp.SystemBuffer;
            RtlZeroMemory(pSysBuf, sizeof(*pSysBuf));

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            pSysBuf->AmountInInQueue = (ULONG)C0C_BUFFER_BUSY(&pIoPortLocal->readBuf);

            pIrpWrite = pIoPortLocal->irpQueues[C0C_QUEUE_WRITE].pCurrent;

            if (pIrpWrite) {
                PIO_STACK_LOCATION pIrpStackWrite = IoGetCurrentIrpStackLocation(pIrpWrite);

                if (pIrpStackWrite->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
                        pIrpStackWrite->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_IMMEDIATE_CHAR)
                {
                    pSysBuf->WaitForImmediate = TRUE;
                }
            }

            pSysBuf->AmountInOutQueue = pIoPortLocal->amountInWriteQueue;
            pSysBuf->HoldReasons = pIoPortLocal->writeHolding;

            if ((pIoPortLocal->handFlow.ControlHandShake & SERIAL_DSR_SENSITIVITY) &&
                    (pIoPortLocal->modemStatus & C0C_MSB_DSR) == 0)
            {
                pSysBuf->HoldReasons |= SERIAL_RX_WAITING_FOR_DSR;
            }

            if (pIoPortLocal->writeHoldingRemote & SERIAL_TX_WAITING_FOR_XON)
                pSysBuf->HoldReasons |= SERIAL_TX_WAITING_XOFF_SENT;

            pSysBuf->Errors = pIoPortLocal->errors;
            pIoPortLocal->errors = 0;

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);

            pIrp->IoStatus.Information = sizeof(SERIAL_STATUS);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);

            break;
        }
        case IOCTL_SERIAL_SET_HANDFLOW: {
            LIST_ENTRY queueToComplete;
            PSERIAL_HANDFLOW pSysBuf;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_HANDFLOW)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PSERIAL_HANDFLOW)pIrp->AssociatedIrp.SystemBuffer;

            if (pSysBuf->ControlHandShake & SERIAL_CONTROL_INVALID ||
                    pSysBuf->FlowReplace & SERIAL_FLOW_INVALID ||
                    (pSysBuf->ControlHandShake & SERIAL_DTR_MASK) == SERIAL_DTR_MASK ||
                    pSysBuf->XonLimit < 0 ||
                    pSysBuf->XoffLimit < 0)
            {
                status = STATUS_INVALID_PARAMETER;
                break;
            }

            InitializeListHead(&queueToComplete);
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            status = SetHandFlow(pIoPortLocal, pSysBuf, &queueToComplete);

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_GET_HANDFLOW:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_HANDFLOW)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIAL_HANDFLOW)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->handFlow;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(SERIAL_HANDFLOW);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_SET_TIMEOUTS:
            status = FdoPortSetTimeouts(pIoPortLocal, pIrp, pIrpStack);
            break;
        case IOCTL_SERIAL_GET_TIMEOUTS:
            status = FdoPortGetTimeouts(pIoPortLocal, pIrp, pIrpStack);
            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_SET_CHARS: {
            PSERIAL_CHARS pSysBuf;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_CHARS)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pSysBuf = (PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer;

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            if (pIoPortLocal->escapeChar &&
                    ((pIoPortLocal->escapeChar == pSysBuf->XoffChar) ||
                     (pIoPortLocal->escapeChar == pSysBuf->XonChar)))
            {
                status = STATUS_INVALID_PARAMETER;
            }

            if (status == STATUS_SUCCESS)
                pIoPortLocal->specialChars = *pSysBuf;

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        }
        case IOCTL_SERIAL_GET_CHARS:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_CHARS)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIAL_CHARS)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->specialChars;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);

            pIrp->IoStatus.Information = sizeof(SERIAL_CHARS);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_LSRMST_INSERT: {
            ULONG Information;
            ULONG optsAndBits;
            UCHAR escapeChar;
            PUCHAR pSysBuf;
            ULONG InputBufferLength;
            BOOLEAN extended;

            InputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;

            if (InputBufferLength < sizeof(UCHAR)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            Information = 0;
            pSysBuf = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;
            escapeChar = *pSysBuf;

            if (InputBufferLength >= (sizeof(UCHAR) + C0CE_SIGNATURE_SIZE + sizeof(ULONG)) &&
                    RtlEqualMemory(pSysBuf + 1, C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE))
            {
                extended = TRUE;
                optsAndBits = *(ULONG *)(pSysBuf + 1 + C0CE_SIGNATURE_SIZE);

#define C0CE_INSERT_OPTS ( \
        C0CE_INSERT_IOCTL_GET| \
        C0CE_INSERT_IOCTL_RXCLEAR)

#define C0CE_INSERT_BITS ( \
        C0CE_INSERT_ENABLE_LSR| \
        C0CE_INSERT_ENABLE_MST| \
        C0CE_INSERT_ENABLE_RBR| \
        C0CE_INSERT_ENABLE_RLC| \
        C0CE_INSERT_ENABLE_LSR_BI)

#define C0CE_INSERT_CAPS (C0CE_INSERT_OPTS|C0CE_INSERT_BITS)

                if (optsAndBits == C0CE_INSERT_IOCTL_CAPS) {
                    optsAndBits = 0;

                    Information += C0CE_SIGNATURE_SIZE + sizeof(ULONG);

                    if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < Information) {
                        status = STATUS_BUFFER_TOO_SMALL;
                        break;
                    }

                    RtlCopyMemory(pSysBuf, C0CE_SIGNATURE, C0CE_SIGNATURE_SIZE);
                    *(ULONG *)(pSysBuf + C0CE_SIGNATURE_SIZE) = C0CE_INSERT_CAPS;
                } else {
                    if (optsAndBits & ~C0CE_INSERT_CAPS) {
                        status = STATUS_INVALID_PARAMETER;
                        break;
                    }

                    if (optsAndBits & C0CE_INSERT_IOCTL_GET) {
                        if (optsAndBits & (C0CE_INSERT_ENABLE_LSR|C0CE_INSERT_ENABLE_LSR_BI))
                            Information += sizeof(UCHAR)*2 + sizeof(UCHAR);
                        if (optsAndBits & C0CE_INSERT_ENABLE_MST)
                            Information += sizeof(UCHAR)*2 + sizeof(UCHAR);
                        if (optsAndBits & C0CE_INSERT_ENABLE_RBR)
                            Information += sizeof(UCHAR)*2 + sizeof(ULONG);
                        if (optsAndBits & C0CE_INSERT_ENABLE_RLC)
                            Information += sizeof(UCHAR)*2 + sizeof(UCHAR)*3;
                    }

                    if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < Information) {
                        status = STATUS_BUFFER_TOO_SMALL;
                        break;
                    }
                }
            } else {
                extended = FALSE;
                optsAndBits = (C0CE_INSERT_ENABLE_LSR|C0CE_INSERT_ENABLE_MST);
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            if (escapeChar && ((escapeChar == pIoPortLocal->specialChars.XoffChar) ||
                               (escapeChar == pIoPortLocal->specialChars.XonChar) ||
                               (pIoPortLocal->handFlow.FlowReplace & SERIAL_ERROR_CHAR)))
            {
                status = STATUS_INVALID_PARAMETER;
                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                break;
            }

            pIoPortLocal->insertMask = optsAndBits & C0CE_INSERT_BITS;
            pIoPortLocal->escapeChar = escapeChar;

            if (extended) {
                LIST_ENTRY queueToComplete;
                PC0C_IO_PORT pIoPortRemote;

                InitializeListHead(&queueToComplete);
                pIoPortRemote = pIoPortLocal->pIoPortRemote;

                if (optsAndBits & C0CE_INSERT_IOCTL_GET) {
                    if (optsAndBits & (C0CE_INSERT_ENABLE_LSR|C0CE_INSERT_ENABLE_LSR_BI)) {
                        UCHAR lsr = 0;

                        if (C0C_TX_BUFFER_THR_EMPTY(&pIoPortLocal->txBuf)) {
                            lsr |= 0x20;  /* transmit holding register empty */

                            if (C0C_TX_BUFFER_EMPTY(&pIoPortLocal->txBuf))
                                lsr |= 0x40;  /* transmit holding register empty and line is idle */
                        }

                        if ((optsAndBits & C0CE_INSERT_ENABLE_LSR_BI) != 0 && pIoPortLocal->rcvdBreak)
                            lsr |= 0x10;  /* break interrupt indicator */

                        *pSysBuf++ = escapeChar;
                        *pSysBuf++ = SERIAL_LSRMST_LSR_NODATA;
                        *pSysBuf++ = lsr;
                    }

                    if (optsAndBits & C0CE_INSERT_ENABLE_MST) {
                        *pSysBuf++ = escapeChar;
                        *pSysBuf++ = SERIAL_LSRMST_MST;
                        *pSysBuf++ = pIoPortLocal->modemStatus;
                    }

                    if (optsAndBits & C0CE_INSERT_ENABLE_RBR) {
                        *pSysBuf++ = escapeChar;
                        *pSysBuf++ = C0CE_INSERT_RBR;
                        *(ULONG *)pSysBuf = pIoPortRemote->baudRate.BaudRate;
                        pSysBuf += sizeof(ULONG);
                    }

                    if (optsAndBits & C0CE_INSERT_ENABLE_RLC) {
                        *pSysBuf++ = escapeChar;
                        *pSysBuf++ = C0CE_INSERT_RLC;
                        *pSysBuf++ = pIoPortRemote->lineControl.WordLength;
                        *pSysBuf++ = pIoPortRemote->lineControl.Parity;
                        *pSysBuf++ = pIoPortRemote->lineControl.StopBits;
                    }
                }

                pIrp->IoStatus.Information = Information;

                if (optsAndBits & C0CE_INSERT_IOCTL_RXCLEAR) {
                    PurgeBuffer(&pIoPortLocal->readBuf);
                    UpdateHandFlow(pIoPortLocal, TRUE, &queueToComplete);
                    if (pIoPortLocal->tryWrite || pIoPortRemote->tryWrite) {
                        ReadWrite(
                            pIoPortLocal, FALSE,
                            pIoPortRemote, FALSE,
                            &queueToComplete);
                    }
                }

                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                FdoPortCompleteQueue(&queueToComplete);

                TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
                break;
            }

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        }
        case IOCTL_SERIAL_SET_LINE_CONTROL: {
            PSERIAL_LINE_CONTROL pLineControl;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_LINE_CONTROL)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pLineControl = (PSERIAL_LINE_CONTROL)pIrp->AssociatedIrp.SystemBuffer;

            switch (pLineControl->WordLength) {
            case 5:
            case 6:
            case 7:
            case 8:
                break;
            default:
                status = STATUS_INVALID_PARAMETER;
            }

            switch (pLineControl->Parity) {
            case NO_PARITY:
            case ODD_PARITY:
            case EVEN_PARITY:
            case MARK_PARITY:
            case SPACE_PARITY:
                break;
            default:
                status = STATUS_INVALID_PARAMETER;
            }

            switch (pLineControl->StopBits) {
            case STOP_BIT_1:
            case STOP_BITS_1_5:
            case STOP_BITS_2:
                break;
            default:
                status = STATUS_INVALID_PARAMETER;
            }

            if (status == STATUS_INVALID_PARAMETER)
                break;

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            if (pIoPortLocal->lineControl.StopBits != pLineControl->StopBits ||
                    pIoPortLocal->lineControl.Parity != pLineControl->Parity ||
                    pIoPortLocal->lineControl.WordLength != pLineControl->WordLength)
            {
                PC0C_IO_PORT pIoPortRemote;

                pIoPortLocal->lineControl = *pLineControl;
                SetWriteDelay(pIoPortLocal);

                pIoPortRemote = pIoPortLocal->pIoPortRemote;

                if (pIoPortRemote->escapeChar && (pIoPortRemote->insertMask & C0CE_INSERT_ENABLE_RLC)) {
                    LIST_ENTRY queueToComplete;

                    InitializeListHead(&queueToComplete);

                    InsertRemoteLc(pIoPortRemote, &queueToComplete);

                    if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                        ReadWrite(
                            pIoPortLocal, FALSE,
                            pIoPortLocal->pIoPortRemote, FALSE,
                            &queueToComplete);
                    }

                    KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                    FdoPortCompleteQueue(&queueToComplete);
                    break;
                }
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        }
        case IOCTL_SERIAL_GET_LINE_CONTROL:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_LINE_CONTROL)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIAL_LINE_CONTROL)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->lineControl;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(SERIAL_LINE_CONTROL);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_SET_BAUD_RATE: {
            PSERIAL_BAUD_RATE pBaudRate;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_BAUD_RATE)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pBaudRate = (PSERIAL_BAUD_RATE)pIrp->AssociatedIrp.SystemBuffer;

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            if (pIoPortLocal->baudRate.BaudRate != pBaudRate->BaudRate) {
                PC0C_IO_PORT pIoPortRemote;

                pIoPortLocal->baudRate = *pBaudRate;
                SetWriteDelay(pIoPortLocal);

                pIoPortRemote = pIoPortLocal->pIoPortRemote;

                if (pIoPortRemote->escapeChar && (pIoPortRemote->insertMask & C0CE_INSERT_ENABLE_RBR)) {
                    LIST_ENTRY queueToComplete;

                    InitializeListHead(&queueToComplete);

                    InsertRemoteBr(pIoPortRemote, &queueToComplete);

                    if (pIoPortLocal->pIoPortRemote->tryWrite || pIoPortLocal->tryWrite) {
                        ReadWrite(
                            pIoPortLocal, FALSE,
                            pIoPortLocal->pIoPortRemote, FALSE,
                            &queueToComplete);
                    }

                    KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                    FdoPortCompleteQueue(&queueToComplete);
                    break;
                }
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        }
        case IOCTL_SERIAL_GET_BAUD_RATE:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_BAUD_RATE)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIAL_BAUD_RATE)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->baudRate;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(SERIAL_BAUD_RATE);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_GET_PROPERTIES: {
            ULONG size;

            status = GetCommProp(pDevExt,
                                 pIrp->AssociatedIrp.SystemBuffer,
                                 pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
                                 &size);

            if (status == STATUS_SUCCESS) {
                pIrp->IoStatus.Information = size;
                TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            }

            break;
        }
        case IOCTL_SERIAL_CONFIG_SIZE:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }
            pIrp->IoStatus.Information = sizeof(ULONG);
            *(PULONG)pIrp->AssociatedIrp.SystemBuffer = 0;
            break;
        case IOCTL_SERIAL_SET_QUEUE_SIZE: {
            PSERIAL_QUEUE_SIZE pSysBuf = (PSERIAL_QUEUE_SIZE)pIrp->AssociatedIrp.SystemBuffer;
            LIST_ENTRY queueToComplete;
            PC0C_BUFFER pReadBuf;
            PUCHAR pBase;

            if (pIrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SERIAL_QUEUE_SIZE)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            pReadBuf = &pIoPortLocal->readBuf;

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            if (pSysBuf->InSize <= C0C_BUFFER_SIZE(pReadBuf)) {
                KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
                break;
            }
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);

            try {
                pBase = C0C_ALLOCATE_POOL_WITH_QUOTA(NonPagedPool, pSysBuf->InSize);
            }
            except (EXCEPTION_EXECUTE_HANDLER) {
                pBase = NULL;
                status = GetExceptionCode();
            }

            if (!pBase)
                break;

            InitializeListHead(&queueToComplete);
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);

            if (SetNewBufferBase(pReadBuf, pBase, pSysBuf->InSize)) {
                pIoPortLocal->handFlow.XoffLimit = pSysBuf->InSize >> 3;
                pIoPortLocal->handFlow.XonLimit = pSysBuf->InSize >> 1;
                SetLimit(pIoPortLocal);
                UpdateHandFlow(pIoPortLocal, TRUE, &queueToComplete);
                if (pIoPortLocal->tryWrite || pIoPortLocal->pIoPortRemote->tryWrite) {
                    ReadWrite(
                        pIoPortLocal, FALSE,
                        pIoPortLocal->pIoPortRemote, FALSE,
                        &queueToComplete);
                }
            }

            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            FdoPortCompleteQueue(&queueToComplete);
            break;
        }
        case IOCTL_SERIAL_GET_STATS:
            if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIALPERF_STATS)) {
                status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            *(PSERIALPERF_STATS)pIrp->AssociatedIrp.SystemBuffer = pIoPortLocal->perfStats;
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            pIrp->IoStatus.Information = sizeof(SERIALPERF_STATS);

            TraceIrp("FdoPortIoCtl", pIrp, &status, TRACE_FLAG_RESULTS);
            break;
        case IOCTL_SERIAL_CLEAR_STATS:
            KeAcquireSpinLock(pIoPortLocal->pIoLock, &oldIrql);
            RtlZeroMemory(&pIoPortLocal->perfStats, sizeof(pIoPortLocal->perfStats));
            KeReleaseSpinLock(pIoPortLocal->pIoLock, oldIrql);
            break;
        default:
            status = STATUS_INVALID_PARAMETER;
        }
    }
Example #9
0
void CChannel::SetModes ( const CString& szModes, const std::vector < CString >& vecModeParams )
{
    unsigned int uiParamIndex = 0;
    enum { ADD, DEL } eDirection = ADD;
    CServer& me = CProtocol::GetSingleton ().GetMe ();

    const char* p = szModes.c_str ();
    while ( *p != '\0' )
    {
        switch ( *p )
        {
        case '+':
        {
            eDirection = ADD;
            break;
        }
        case '-':
        {
            eDirection = DEL;
            break;
        }
        default:
        {
            unsigned long ulMode = ms_ulChannelModes [ (unsigned char)*p ];
            if ( ulMode != 0 )
            {
                if ( ulMode < CMODE_PARAMSMAX )
                {
                    if ( eDirection == ADD )
                        m_ulModes |= ulMode;
                    else
                        m_ulModes &= ~ulMode;

                    if ( ulMode >= CMODE_MAX )
                    {
                        // El modo lleva parámetros
                        switch ( ulMode )
                        {
                        case CMODE_KEY:
                            if ( eDirection == ADD )
                                SetKey ( vecModeParams [ uiParamIndex ] );
                            else
                                SetKey ( "" );
                            ++uiParamIndex;
                            break;
                        case CMODE_LIMIT:
                            if ( eDirection == ADD )
                            {
                                SetLimit ( atoi ( vecModeParams [ uiParamIndex ] ) );
                                ++uiParamIndex;
                            }
                            else
                                SetLimit ( 0 );
                            break;
                        }
                    }
                }
                else
                {
                    // Cambiamos flags de usuarios o bans
                    if ( ulMode == CFLAG_BAN )
                    {
                        if ( eDirection == ADD )
                            AddBan ( vecModeParams [ uiParamIndex ] );
                        else
                            RemoveBan ( vecModeParams [ uiParamIndex ] );
                        ++uiParamIndex;
                    }
                    else
                    {
                        CUser* pUser = me.GetUserAnywhere ( base64toint ( vecModeParams [ uiParamIndex ] ) );
                        ++uiParamIndex;

                        if ( pUser )
                        {
                            CMembership* pMembership = GetMembership ( pUser );
                            if ( pMembership )
                            {
                                unsigned long ulCurFlags = pMembership->GetFlags ();
                                if ( eDirection == ADD )
                                    pMembership->SetFlags ( ulCurFlags | ulMode );
                                else
                                    pMembership->SetFlags ( ulCurFlags & ~ulMode );
                            }
                        }
                    }
                }
            }
        }
        }
        ++p;
    }
}
Example #10
0
int handlemodemsg(void *source, int cargc, char **cargv) {
  channel *cp;
  int dir=1;
  int arg=2;
  char *modestr;
  unsigned long *lp;
  void *harg[4];
  nick *np, *target;
  int hooknum;
  int changes=0;

  if (cargc<2) {
    return CMD_OK;
  }

  if (cargv[0][0]!='#' && cargv[0][0]!='+') {
    /* Not a channel, ignore */
    return CMD_OK;
  }

  if ((cp=findchannel(cargv[0]))==NULL) {
    /* No channel, abort */
    Error("channel",ERR_WARNING,"Mode change on non-existent channel %s",cargv[0]);
    return CMD_OK;
  }
  
  if (((char *)source)[2]=='\0') {
    /* Server mode change, treat as divine intervention */
    np=NULL;
  } else if ((np=getnickbynumericstr((char *)source))==NULL) {
    /* No sender, continue but moan */
    Error("channel",ERR_WARNING,"Mode change by non-existent user %s on channel %s",(char *)source,cp->index->name->content);
  }
  
  /* Set up the hook data */
  harg[0]=cp;
  harg[1]=np;
  harg[3]=(void *)(long)(cp->flags);
  
  /* Process the mode string one character at a time */
  /* Maybe I'll write this more intelligently one day if I can comprehend the ircu code that does this */
  for (modestr=cargv[1];*modestr;modestr++) {
    switch(*modestr) {
      /* Set whether we are adding or removing modes */
      
      case '+': 
        dir=1;
        break;
        
      case '-':
        dir=0;
        break;
      
      /* Simple modes: just set or clear based on value of dir */
      
      case 'n':
        if (dir) { SetNoExtMsg(cp); } else { ClearNoExtMsg(cp); }
	changes |= MODECHANGE_MODES;
        break;
      
      case 't':
        if (dir) { SetTopicLimit(cp); } else { ClearTopicLimit(cp); }
	changes |= MODECHANGE_MODES;
        break;
      
      case 's':
        if (dir) { SetSecret(cp); ClearPrivate(cp); } else { ClearSecret(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'p':
        if (dir) { SetPrivate(cp); ClearSecret(cp); } else { ClearPrivate(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'i':
        if (dir) { SetInviteOnly(cp); } else { ClearInviteOnly(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'm':
        if (dir) { SetModerated(cp); } else { ClearModerated(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'c':
        if (dir) { SetNoColour(cp); } else { ClearNoColour(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'C':
        if (dir) { SetNoCTCP(cp); } else { ClearNoCTCP(cp); }
	changes |= MODECHANGE_MODES;
        break;
      
      case 'r':
        if (dir) { SetRegOnly(cp); } else { ClearRegOnly(cp); }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'D':
        if (dir) { SetDelJoins(cp); } else { ClearDelJoins(cp); }
	changes |= MODECHANGE_MODES;
        break;

      case 'u':
        if (dir) { SetNoQuitMsg(cp); } else { ClearNoQuitMsg(cp); }
        changes |= MODECHANGE_MODES;
        break;
      
      case 'N':
        if (dir) { SetNoNotice(cp); } else { ClearNoNotice(cp); }
        changes |= MODECHANGE_MODES;
        break;
        
      case 'M':
        if (dir) { SetModNoAuth(cp); } else { ClearModNoAuth(cp); }
        changes |= MODECHANGE_MODES;
        break;
      
      case 'T':
        if (dir) { SetSingleTarg(cp); } else { ClearSingleTarg(cp); }
        changes |= MODECHANGE_MODES;
        break;
        
      /* Parameter modes: advance parameter and possibly read it in */    
    
      case 'l':
        if (dir) {
          /* +l uses a parameter, but -l does not.
           * If there is no parameter, don't set the mode.
           * I guess we should moan too in that case, but 
           * they might be even nastier to us if we do ;) */
          if (arg<cargc) {
            cp->limit=strtol(cargv[arg++],NULL,10);
            SetLimit(cp);
          }      
        } else {
          ClearLimit(cp);
          cp->limit=0;
        }
	changes |= MODECHANGE_MODES;
        break;
        
      case 'k':
        if (dir) {
          /* +k uses a parameter in both directions */
          if (arg<cargc) {
            freesstring(cp->key); /* It's probably NULL, but be safe */
            cp->key=getsstring(cargv[arg++],KEYLEN);
            SetKey(cp);
          }
        } else {
          freesstring(cp->key);
          cp->key=NULL;
          ClearKey(cp);
          arg++; /* Eat the arg without looking at it, even if it's not there */
        }
	changes |= MODECHANGE_MODES;
        break;
        
      /* Op/Voice */
      
      case 'o':
      case 'v': 
        if (arg<cargc) {
          if((lp=getnumerichandlefromchanhash(cp->users,numerictolong(cargv[arg++],5)))==NULL) {
            /* They're not on the channel; MODE crossed with part/kill/kick/blah */
            Error("channel",ERR_DEBUG,"Mode change for user %s not on channel %s",cargv[arg-1],cp->index->name->content);
          } else { 
            if ((target=getnickbynumeric(*lp))==NULL) {
              /* This really is a fuckup, we found them on the channel but there isn't a user with that numeric */
              /* This means there's a serious bug in the nick/channel tracking code */
              Error("channel",ERR_ERROR,"Mode change for user %s on channel %s who doesn't exist",cargv[arg-1],cp->index->name->content);
            } else { /* Do the mode change whilst admiring the beautiful code layout */
              harg[2]=target;
              if (*modestr=='o') { if (dir) { *lp |= CUMODE_OP;     hooknum=HOOK_CHANNEL_OPPED;    } else 
                                            { *lp &= ~CUMODE_OP;    hooknum=HOOK_CHANNEL_DEOPPED;  } }
                            else { if (dir) { *lp |= CUMODE_VOICE;  hooknum=HOOK_CHANNEL_VOICED;   } else 
                                            { *lp &= ~CUMODE_VOICE; hooknum=HOOK_CHANNEL_DEVOICED; } } 
              triggerhook(hooknum,harg);
            }
          }
        }
	changes |= MODECHANGE_USERS;
        break;
        
      case 'b':
        if (arg<cargc) {
          if (dir) {
            setban(cp,cargv[arg++]);
            triggerhook(HOOK_CHANNEL_BANSET,harg);
          } else {
            clearban(cp,cargv[arg++],0);
            triggerhook(HOOK_CHANNEL_BANCLEAR,harg);
          }
        }
	changes |= MODECHANGE_BANS;
        break;
        
      default:
        Error("channel",ERR_DEBUG,"Unknown mode char '%c' %s on %s",*modestr,dir?"set":"cleared",cp->index->name->content);
        break;
    }
  }

  harg[2]=(void *)((long)changes);
  triggerhook(HOOK_CHANNEL_MODECHANGE,(void *)harg);  
  return CMD_OK;
}
Example #11
0
int handleburstmsg(void *source, int cargc, char **cargv) {
  channel *cp;
  time_t timestamp;
  int wipeout=0;
  int i;
  int arg=0;
  char *charp;
  int newlimit;
  int waslimit,waskeyed;
  char *nextnum;
  unsigned long currentmode;
  int isnewchan;
  
  /* (we don't see the first 2 params in cargc) */
  /* AK B #+lod+ 1017561154 +tnk eits ATJWu:o,AiW1a,Ag3lV,AiWnl,AE6oI :%*[email protected] */
  
  if (cargc<2) {
    Error("channel",ERR_WARNING,"Burst message with only %d parameters",cargc);
    return CMD_OK;
  }
  
  timestamp=strtol(cargv[1],NULL,10);
  
  if ((cp=findchannel(cargv[0]))==NULL) {
    /* We don't have this channel already */
    cp=createchannel(cargv[0]);
    cp->timestamp=timestamp;
    isnewchan=1;
  } else {
    isnewchan=0;
    if (timestamp<cp->timestamp) {
      /* The incoming timestamp is older.  Erase all our current channel modes, and the topic. */
      cp->timestamp=timestamp;
      freesstring(cp->topic);
      cp->topic=NULL;
      cp->topictime=0;
      freesstring(cp->key);
      cp->key=NULL;
      cp->limit=0;
      cp->flags=0;
      clearallbans(cp);
      /* Remove all +v, +o we currently have */
      for(i=0;i<cp->users->hashsize;i++) {
        if (cp->users->content[i]!=nouser) {
          cp->users->content[i]&=CU_NUMERICMASK;
        }
      }
    } else if (timestamp>cp->timestamp) {
      /* The incoming timestamp is greater.  Ignore any incoming modes they may happen to set */
      wipeout=1;
    }
  }

  /* OK, dealt with the name and timestamp. 
   * Loop over the remaining args */
  for (arg=2;arg<cargc;arg++) {
    if (cargv[arg][0]=='+') {
      /* Channel modes */
      if (wipeout) {
        /* We ignore the modes, but we need to see if they include +l or +k 
         * so that we can ignore their corresponding values */
        for (charp=cargv[arg];*charp;charp++) {
          if (*charp=='k' || *charp=='l') {
            arg++;
          }
        }
      } else {
        /* Clear off the limit and key flags before calling setflags so we can see if the burst tried to set them */
        /* If the burst doesn't set them, we restore them afterwards */
        waslimit=IsLimit(cp); ClearLimit(cp);
        waskeyed=IsKey(cp);   ClearKey(cp);
        /* We can then use the flag function for these modes */
        setflags(&(cp->flags),CHANMODE_ALL,cargv[arg],cmodeflags,REJECT_NONE);
        /* Pick up the limit and key, if they were set.  Note that the limit comes first */
        if (IsLimit(cp)) { /* A limit was SET by the burst */
          if (++arg>=cargc) {
            /* Ran out of args -- damn ircd is spewing out crap again */
            Error("channel",ERR_WARNING,"Burst +l with no argument");
            break; /* "break" being the operative word */
          } else {
            newlimit=strtol(cargv[arg],NULL,10);
          }
          if (cp->limit>0 && waslimit) {
            /* We had a limit before -- we now have the lowest one of the two */
            if (newlimit<cp->limit) {
              cp->limit=newlimit;
            }
          } else {
            /* No limit before -- we just have the new one */
            cp->limit=newlimit;
          }
        } else if (waslimit) {
          SetLimit(cp); /* We had a limit before, but the burst didn't set one.  Restore flag. */
        }
        
        if (IsKey(cp)) { /* A key was SET by the burst */
          if (++arg>=cargc) {
            /* Ran out of args -- oopsie! */
            Error("channel",ERR_WARNING,"Burst +k with no argument");
            break;
          }
          if (waskeyed) {
            /* We had a key before -- alphabetically first wins */
            if (ircd_strcmp(cargv[arg],cp->key->content)<0) {
              /* Replace our key */
              freesstring(cp->key);
              cp->key=getsstring(cargv[arg],KEYLEN);
            }
          } else {
            /* No key before -- just the new one */
            cp->key=getsstring(cargv[arg],KEYLEN);
          }
        } else if (waskeyed) {
          SetKey(cp); /* We had a key before, but the burst didn't set one.  Restore flag. */
        }
      }       
    } else if (cargv[arg][0]=='%') {
      /* We have one or more bans here */
      nextnum=cargv[arg]+1;
      while (*nextnum) {
        /* Split off the next ban */
        for (charp=nextnum;*charp;charp++) {
          if (*charp==' ') {
            *charp='\0';
            charp++;
            break;
          }
        }        
        setban(cp,nextnum);
        nextnum=charp;
      }
    } else {
      /* List of numerics */
      nextnum=charp=cargv[arg];
      currentmode=0;
      while (*nextnum!='\0') {
        /* Step over the next numeric */
        for (i=0;i<5;i++) {
          if (*charp++=='\0')
            break;
        }
        if (i<5) {
          break;
        }
        if (*charp==',') {
          *charp='\0';
          charp++;
        } else if (*charp==':') {
          *charp='\0';
          charp++;
          currentmode=0;
          /* Look for modes */
          for (;*charp;charp++) {
            if (*charp=='v') {
              currentmode|=CUMODE_VOICE;
            } else if (*charp=='o') {
              currentmode|=CUMODE_OP;
            } else if (*charp==',') {
              charp++;
              break;
            }
          }
          /* If we're ignore incoming modes, zap it to zero again */
          if (wipeout) {
            currentmode=0;
          }
        }
        /* OK.  At this point charp points to either '\0' if we're at the end,
         * or the start of the next numeric otherwise.  nextnum points at a valid numeric
         * we need to add, and currentmode reflects the correct mode */
        addnicktochannel(cp,(numerictolong(nextnum,5)|currentmode));
        nextnum=charp;
      }
    }
  }
  if (cp->users->totalusers==0) {
    /* Oh dear, the channel is now empty.  Perhaps one of those 
     * charming empty burst messages you get sometimes.. */
    if (!isnewchan) {
      /* I really don't think this can happen, can it..? */
      /* Only send the LOSTCHANNEL if the channel existed before */
      triggerhook(HOOK_CHANNEL_LOSTCHANNEL,cp);
    }
    delchannel(cp);
  } else {
    /* If this is a new channel, we do the NEWCHANNEL hook also */
    if (isnewchan) {
      triggerhook(HOOK_CHANNEL_NEWCHANNEL,cp);
    }
    /* Just one hook to say "something happened to this channel" */
    triggerhook(HOOK_CHANNEL_BURST,cp);       
  }
   
  return CMD_OK;     
}
Example #12
0
NTSTATUS SetHandFlow(
    PC0C_IO_PORT pIoPort,
    PSERIAL_HANDFLOW pHandFlow,
    PLIST_ENTRY pQueueToComplete)
{
  UCHAR bits, mask;
  PC0C_BUFFER pReadBuf;
  PSERIAL_HANDFLOW pNewHandFlow;
  BOOLEAN setModemStatusHolding;

  pReadBuf = &pIoPort->readBuf;

  if (pHandFlow) {
    if ((pIoPort->escapeChar && (pHandFlow->FlowReplace & SERIAL_ERROR_CHAR)) ||
        ((SIZE_T)pHandFlow->XonLimit > C0C_BUFFER_SIZE(pReadBuf)) ||
        ((SIZE_T)pHandFlow->XoffLimit > C0C_BUFFER_SIZE(pReadBuf)))
    {
      return STATUS_INVALID_PARAMETER;
    }

    pNewHandFlow = pHandFlow;
  } else {
    pNewHandFlow = &pIoPort->handFlow;
  }

  // Set local side
  if (!pHandFlow)
    pIoPort->writeHolding &= ~SERIAL_TX_WAITING_FOR_XON;

  if (pHandFlow &&
      ((pIoPort->handFlow.FlowReplace & SERIAL_AUTO_TRANSMIT) != 0) &&
      ((pHandFlow->FlowReplace & SERIAL_AUTO_TRANSMIT) == 0))
  {
    SetXonXoffHolding(pIoPort, C0C_XCHAR_ON);
  }

  if (!pHandFlow ||
      (pIoPort->handFlow.ControlHandShake & SERIAL_OUT_HANDSHAKEMASK) !=
          (pHandFlow->ControlHandShake & SERIAL_OUT_HANDSHAKEMASK))
  {
    setModemStatusHolding = TRUE;
  } else {
    setModemStatusHolding = FALSE;
  }

  // Set remote side
  bits = mask = 0;

  if (!pHandFlow ||
      (pIoPort->handFlow.FlowReplace & SERIAL_RTS_MASK) !=
          (pHandFlow->FlowReplace & SERIAL_RTS_MASK))
  {
    switch (pNewHandFlow->FlowReplace & SERIAL_RTS_MASK) {
    case 0:
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_CTS;
      mask |= C0C_MCR_RTS;
      break;
    case SERIAL_RTS_CONTROL:
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_CTS;
      bits |= C0C_MCR_RTS;
      mask |= C0C_MCR_RTS;
      break;
    case SERIAL_RTS_HANDSHAKE:
      if (C0C_BUFFER_BUSY(pReadBuf) > (C0C_BUFFER_SIZE(pReadBuf) - pNewHandFlow->XoffLimit)) {
        pIoPort->writeHoldingRemote |= SERIAL_TX_WAITING_FOR_CTS;
        mask |= C0C_MCR_RTS;
      }
      else
      if (pIoPort->writeHoldingRemote & SERIAL_TX_WAITING_FOR_CTS) {
        if (C0C_BUFFER_BUSY(pReadBuf) <= (SIZE_T)pNewHandFlow->XonLimit) {
          pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_CTS;
          bits |= C0C_MCR_RTS;
          mask |= C0C_MCR_RTS;
        }
      }
      else {
        bits |= C0C_MCR_RTS;
        mask |= C0C_MCR_RTS;
      }
    }
  }

  if (!pHandFlow ||
      (pIoPort->handFlow.ControlHandShake & SERIAL_DTR_MASK) !=
          (pHandFlow->ControlHandShake & SERIAL_DTR_MASK))
  {
    switch (pNewHandFlow->ControlHandShake & SERIAL_DTR_MASK) {
    case 0:
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_DSR;
      mask |= C0C_MCR_DTR;
      break;
    case SERIAL_DTR_CONTROL:
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_DSR;
      bits |= C0C_MCR_DTR;
      mask |= C0C_MCR_DTR;
      break;
    case SERIAL_DTR_HANDSHAKE:
      if (C0C_BUFFER_BUSY(pReadBuf) > (C0C_BUFFER_SIZE(pReadBuf) - pNewHandFlow->XoffLimit)) {
        pIoPort->writeHoldingRemote |= SERIAL_TX_WAITING_FOR_DSR;
        mask |= C0C_MCR_DTR;
      }
      else
      if (pIoPort->writeHoldingRemote & SERIAL_TX_WAITING_FOR_DSR) {
        if (C0C_BUFFER_BUSY(pReadBuf) <= (SIZE_T)pNewHandFlow->XonLimit) {
          pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_DSR;
          bits |= C0C_MCR_DTR;
          mask |= C0C_MCR_DTR;
        }
      }
      else {
        bits |= C0C_MCR_DTR;
        mask |= C0C_MCR_DTR;
      }
    }
  }

  if (!pHandFlow ||
      (pIoPort->handFlow.FlowReplace & SERIAL_AUTO_RECEIVE) !=
          (pHandFlow->FlowReplace & SERIAL_AUTO_RECEIVE))
  {
    if (pNewHandFlow->FlowReplace & SERIAL_AUTO_RECEIVE) {
      if (C0C_BUFFER_BUSY(pReadBuf) > (C0C_BUFFER_SIZE(pReadBuf) - pNewHandFlow->XoffLimit)) {
        pIoPort->writeHoldingRemote |= SERIAL_TX_WAITING_FOR_XON;
        if ((pNewHandFlow->FlowReplace & SERIAL_XOFF_CONTINUE) == 0)
          pIoPort->writeHolding |= SERIAL_TX_WAITING_FOR_XON;
        pIoPort->sendXonXoff = C0C_XCHAR_OFF;
        pIoPort->tryWrite = TRUE;
      }
    }
    else
    if (pIoPort->writeHoldingRemote & SERIAL_TX_WAITING_FOR_XON) {
      pIoPort->writeHoldingRemote &= ~SERIAL_TX_WAITING_FOR_XON;
      pIoPort->writeHolding &= ~SERIAL_TX_WAITING_FOR_XON;
      if (pIoPort->sendXonXoff != C0C_XCHAR_OFF) {
        // XOFF was sent so send XON
        pIoPort->sendXonXoff = C0C_XCHAR_ON;
        pIoPort->tryWrite = TRUE;
      } else {
        // XOFF still was not sent so cancel it
        pIoPort->sendXonXoff = 0;
      }
    }
  }

  if (pHandFlow)
    pIoPort->handFlow = *pHandFlow;

  if (setModemStatusHolding)
    SetModemStatusHolding(pIoPort);

  if (mask)
    SetModemControl(pIoPort, bits, mask, pQueueToComplete);

  UpdateTransmitToggle(pIoPort, pQueueToComplete);

  SetLimit(pIoPort->pIoPortRemote);
  SetLimit(pIoPort);

  if (pIoPort->pIoPortRemote->tryWrite) {
    ReadWrite(
        pIoPort, FALSE,
        pIoPort->pIoPortRemote, FALSE,
        pQueueToComplete);
  }

  if (pIoPort->tryWrite) {
    ReadWrite(
        pIoPort->pIoPortRemote, FALSE,
        pIoPort, FALSE,
        pQueueToComplete);
  }

  return STATUS_SUCCESS;
}