BinaryEditor::BinaryEditor(Binary *b, QWidget *parent) :Editor(b, parent), ressource(b) { descriptionWidget = new QLineEdit(ressource->getDescription()); QObject::connect(descriptionWidget, SIGNAL(textChanged(QString)), this, SLOT(UI_ENABLE_SAVE_BUTTON_AND_UPDATE_SIDEBAR())); QObject::connect(this, SIGNAL(destroyed()), this, SLOT(CLOSING())); }
//* TdiQueryInfoEx - Extended TDI query information. // // This is the new TDI query information handler. We take in a TDIObjectID // structure, a buffer and length, and some context information, and return // the requested information if possible. // // Input: Request - The request structure for this command. // ID - The object ID // Buffer - Pointer to buffer to be filled in. // Size - Pointer to size in bytes of Buffer. On exit, // filled in with bytes written. // Context - Pointer to context buffer. // // Returns: Status of attempt to get information. // TDI_STATUS TdiQueryInformationEx(PTDI_REQUEST Request, TDIObjectID *ID, PNDIS_BUFFER Buffer, uint *Size, void *Context) { uint BufferSize = *Size; uint InfoSize; void *InfoPtr; uint Fixed; CTELockHandle Handle; #ifndef VXD CTELock *LockPtr; #else #ifdef DEBUG CTELock *LockPtr; #endif #endif uint Offset = 0; uchar InfoBuffer[sizeof(TCPConnTableEntry)]; uint BytesRead; uint Valid; uint Entity; uint BytesCopied; // First check to see if he's querying for list of entities. Entity = ID->toi_entity.tei_entity; if (Entity == GENERIC_ENTITY) { *Size = 0; if (ID->toi_class != INFO_CLASS_GENERIC || ID->toi_type != INFO_TYPE_PROVIDER || ID->toi_id != ENTITY_LIST_ID) { return TDI_INVALID_PARAMETER; } // Make sure we have room for it the list in the buffer. InfoSize = EntityCount * sizeof(TDIEntityID); if (BufferSize < InfoSize) { // Not enough room. return TDI_BUFFER_TOO_SMALL; } *Size = InfoSize; // Copy it in, free our temp. buffer, and return success. (void)CopyFlatToNdis(Buffer, (uchar *)EntityList, InfoSize, &Offset, &BytesCopied); return TDI_SUCCESS; } //* Check the level. If it can't be for us, pass it down. #ifndef UDP_ONLY if (Entity != CO_TL_ENTITY && Entity != CL_TL_ENTITY) { #else if (Entity != CL_TL_ENTITY) { #endif // When we support multiple lower entities at this layer we'll have // to figure out which one to dispatch to. For now, just pass it // straight down. return (*LocalNetInfo.ipi_qinfo)(ID, Buffer, Size, Context); } if (ID->toi_entity.tei_instance != TL_INSTANCE) { // We only support a single instance. return TDI_INVALID_REQUEST; } // Zero returned parameters in case of an error below. *Size = 0; if (ID->toi_class == INFO_CLASS_GENERIC) { // This is a generic request. if (ID->toi_type == INFO_TYPE_PROVIDER && ID->toi_id == ENTITY_TYPE_ID) { if (BufferSize >= sizeof(uint)) { *(uint *)&InfoBuffer[0] = (Entity == CO_TL_ENTITY) ? CO_TL_TCP : CL_TL_UDP; (void)CopyFlatToNdis(Buffer, InfoBuffer, sizeof(uint), &Offset, &BytesCopied); return TDI_SUCCESS; } else return TDI_BUFFER_TOO_SMALL; } return TDI_INVALID_PARAMETER; } if (ID->toi_class == INFO_CLASS_PROTOCOL) { // Handle protocol specific class of information. For us, this is // the MIB-2 stuff or the minimal stuff we do for oob_inline support. #ifndef UDP_ONLY if (ID->toi_type == INFO_TYPE_CONNECTION) { TCPConn *Conn; TCB *QueryTCB; TCPSocketAMInfo *AMInfo; CTELockHandle TCBHandle; if (BufferSize < sizeof(TCPSocketAMInfo) || ID->toi_id != TCP_SOCKET_ATMARK) return TDI_INVALID_PARAMETER; AMInfo = (TCPSocketAMInfo *)InfoBuffer; CTEGetLock(&ConnTableLock, &Handle); Conn = GetConnFromConnID((uint)Request->Handle.ConnectionContext); if (Conn != NULL) { CTEStructAssert(Conn, tc); QueryTCB = Conn->tc_tcb; if (QueryTCB != NULL) { CTEStructAssert(QueryTCB, tcb); CTEGetLock(&QueryTCB->tcb_lock, &TCBHandle); if ((QueryTCB->tcb_flags & (URG_INLINE | URG_VALID)) == (URG_INLINE | URG_VALID)) { // We're in inline mode, and the urgent data fields are // valid. AMInfo->tsa_size = QueryTCB->tcb_urgend - QueryTCB->tcb_urgstart + 1; // Rcvnext - pendingcnt is the sequence number of the // next byte of data that will be delivered to the // client. Urgend - that value is the offset in the // data stream of the end of urgent data. AMInfo->tsa_offset = QueryTCB->tcb_urgend - (QueryTCB->tcb_rcvnext - QueryTCB->tcb_pendingcnt); } else { AMInfo->tsa_size = 0; AMInfo->tsa_offset = 0; } CTEFreeLock(&QueryTCB->tcb_lock, TCBHandle); *Size = sizeof(TCPSocketAMInfo); CopyFlatToNdis(Buffer, InfoBuffer, sizeof(TCPSocketAMInfo), &Offset, &BytesCopied); return TDI_SUCCESS; } } return TDI_INVALID_PARAMETER; } #endif if (ID->toi_type != INFO_TYPE_PROVIDER) return TDI_INVALID_PARAMETER; switch (ID->toi_id) { case UDP_MIB_STAT_ID: #if UDP_MIB_STAT_ID != TCP_MIB_STAT_ID case TCP_MIB_STAT_ID: #endif Fixed = TRUE; if (Entity == CL_TL_ENTITY) { InfoSize = sizeof(UDPStats); InfoPtr = &UStats; } else { #ifndef UDP_ONLY InfoSize = sizeof(TCPStats); InfoPtr = &TStats; #else return TDI_INVALID_PARAMETER; #endif } break; case UDP_MIB_TABLE_ID: #if UDP_MIB_TABLE_ID != TCP_MIB_TABLE_ID case TCP_MIB_TABLE_ID: #endif Fixed = FALSE; if (Entity == CL_TL_ENTITY) { InfoSize = sizeof(UDPEntry); InfoPtr = &ReadAOTable; CTEGetLock(&AddrObjTableLock, &Handle); #ifndef VXD LockPtr = &AddrObjTableLock; #else #ifdef DEBUG LockPtr = &AddrObjTableLock; #endif #endif } else { #ifndef UDP_ONLY InfoSize = sizeof(TCPConnTableEntry); InfoPtr = &ReadTCBTable; CTEGetLock(&TCBTableLock, &Handle); #ifndef VXD LockPtr = &TCBTableLock; #else #ifdef DEBUG LockPtr = &TCBTableLock; #endif #endif #else return TDI_INVALID_PARAMETER; #endif } break; default: return TDI_INVALID_PARAMETER; break; } if (Fixed) { if (BufferSize < InfoSize) return TDI_BUFFER_TOO_SMALL; *Size = InfoSize; (void)CopyFlatToNdis(Buffer, InfoPtr, InfoSize, &Offset, &BytesCopied); return TDI_SUCCESS; } else { struct ReadTableStruct *RTSPtr; uint ReadStatus; // Have a variable length (or mult-instance) structure to copy. // InfoPtr points to the structure describing the routines to // call to read the table. // Loop through up to CountWanted times, calling the routine // each time. BytesRead = 0; RTSPtr = InfoPtr; ReadStatus = (*(RTSPtr->rts_validate))(Context, &Valid); // If we successfully read something we'll continue. Otherwise // we'll bail out. if (!Valid) { CTEFreeLock(LockPtr, Handle); return TDI_INVALID_PARAMETER; } while (ReadStatus) { // The invariant here is that there is data in the table to // read. We may or may not have room for it. So ReadStatus // is TRUE, and BufferSize - BytesRead is the room left // in the buffer. if ((int)(BufferSize - BytesRead) >= (int)InfoSize) { ReadStatus = (*(RTSPtr->rts_readnext))(Context, InfoBuffer); BytesRead += InfoSize; Buffer = CopyFlatToNdis(Buffer, InfoBuffer, InfoSize, &Offset, &BytesCopied); } else break; } *Size = BytesRead; CTEFreeLock(LockPtr, Handle); return (!ReadStatus ? TDI_SUCCESS : TDI_BUFFER_OVERFLOW); } } if (ID->toi_class == INFO_CLASS_IMPLEMENTATION) { // We want to return implementation specific info. For now, error out. return TDI_INVALID_PARAMETER; } return TDI_INVALID_PARAMETER; } //* TdiSetInfoEx - Extended TDI set information. // // This is the new TDI set information handler. We take in a TDIObjectID // structure, a buffer and length. We set the object specifed by the ID // (and possibly by the Request) to the value specified in the buffer. // // Input: Request - The request structure for this command. // ID - The object ID // Buffer - Pointer to buffer containing value to set. // Size - Size in bytes of Buffer. // // Returns: Status of attempt to get information. // TDI_STATUS TdiSetInformationEx(PTDI_REQUEST Request, TDIObjectID *ID, void *Buffer, uint Size) { TCPConnTableEntry *TCPEntry; CTELockHandle TableHandle, TCBHandle; TCB *SetTCB; uint Entity; TCPConn *Conn; TDI_STATUS Status; //* Check the level. If it can't be for us, pass it down. Entity = ID->toi_entity.tei_entity; if (Entity != CO_TL_ENTITY && Entity != CL_TL_ENTITY) { // Someday we'll have to figure out how to dispatch. For now, just pass // it down. return (*LocalNetInfo.ipi_setinfo)(ID, Buffer, Size); } if (ID->toi_entity.tei_instance != TL_INSTANCE) return TDI_INVALID_REQUEST; if (ID->toi_class == INFO_CLASS_GENERIC) { // Fill this in when we have generic class defines. return TDI_INVALID_PARAMETER; } //* Now look at the rest of it. if (ID->toi_class == INFO_CLASS_PROTOCOL) { // Handle protocol specific class of information. For us, this is // the MIB-2 stuff, as well as common sockets options, // and in particular the setting of the state of a TCP connection. if (ID->toi_type == INFO_TYPE_CONNECTION) { TCPSocketOption *Option; uint Flag; uint Value; #ifndef UDP_ONLY // A connection type. Get the connection, and then figure out // what to do with it. Status = TDI_INVALID_PARAMETER; if (Size < sizeof(TCPSocketOption)) return Status; CTEGetLock(&ConnTableLock, &TableHandle); Conn = GetConnFromConnID((uint)Request->Handle.ConnectionContext); if (Conn != NULL) { CTEStructAssert(Conn, tc); Status = TDI_SUCCESS; if (ID->toi_id == TCP_SOCKET_WINDOW) { // This is a funny option, because it doesn't involve // flags. Handle this specially. Option = (TCPSocketOption *)Buffer; // We don't allow anyone to shrink the window, as this // gets too weird from a protocol point of view. Also, // make sure they don't try and set anything too big. if (Option->tso_value > 0xffff) Status = TDI_INVALID_PARAMETER; else if (Option->tso_value > Conn->tc_window || Conn->tc_tcb == NULL) { Conn->tc_flags |= CONN_WINSET; Conn->tc_window = Option->tso_value; SetTCB = Conn->tc_tcb; if (SetTCB != NULL) { CTEStructAssert(SetTCB, tcb); CTEGetLock(&SetTCB->tcb_lock, &TCBHandle); CTEAssert(Option->tso_value > SetTCB->tcb_defaultwin); if (DATA_RCV_STATE(SetTCB->tcb_state) && !CLOSING(SetTCB)) { SetTCB->tcb_flags |= WINDOW_SET; SetTCB->tcb_defaultwin = Option->tso_value; SetTCB->tcb_refcnt++; CTEFreeLock(&SetTCB->tcb_lock, TCBHandle); SendACK(SetTCB); CTEGetLock(&SetTCB->tcb_lock, &TCBHandle); DerefTCB(SetTCB, TCBHandle); } else { CTEFreeLock(&SetTCB->tcb_lock, TCBHandle); } } } CTEFreeLock(&ConnTableLock, TableHandle); return Status; } Flag = 0; Option = (TCPSocketOption *)Buffer; Value = Option->tso_value; // We have the connection, so figure out which flag to set. switch (ID->toi_id) { case TCP_SOCKET_NODELAY: Value = !Value; Flag = NAGLING; break; case TCP_SOCKET_KEEPALIVE: Flag = KEEPALIVE; break; case TCP_SOCKET_BSDURGENT: Flag = BSD_URGENT; break; case TCP_SOCKET_OOBINLINE: Flag = URG_INLINE; break; default: Status = TDI_INVALID_PARAMETER; break; } if (Status == TDI_SUCCESS) { if (Value) Conn->tc_tcbflags |= Flag; else Conn->tc_tcbflags &= ~Flag; SetTCB = Conn->tc_tcb; if (SetTCB != NULL) { CTEStructAssert(SetTCB, tcb); CTEGetLock(&SetTCB->tcb_lock, &TCBHandle); if (Value) SetTCB->tcb_flags |= Flag; else SetTCB->tcb_flags &= ~Flag; if (ID->toi_id == TCP_SOCKET_KEEPALIVE) { SetTCB->tcb_alive = TCPTime; SetTCB->tcb_kacount = 0; } CTEFreeLock(&SetTCB->tcb_lock, TCBHandle); } } } CTEFreeLock(&ConnTableLock, TableHandle); return Status; #else return TDI_INVALID_PARAMETER; #endif } if (ID->toi_type == INFO_TYPE_ADDRESS_OBJECT) { // We're setting information on an address object. This is // pretty simple. return SetAddrOptions(Request, ID->toi_id, Size, Buffer); } if (ID->toi_type != INFO_TYPE_PROVIDER) return TDI_INVALID_PARAMETER; #ifndef UDP_ONLY if (ID->toi_id == TCP_MIB_TABLE_ID) { if (Size != sizeof(TCPConnTableEntry)) return TDI_INVALID_PARAMETER; TCPEntry = (TCPConnTableEntry *)Buffer; if (TCPEntry->tct_state != TCP_DELETE_TCB) return TDI_INVALID_PARAMETER; // We have an apparently valid request. Look up the TCB. CTEGetLock(&TCBTableLock, &TableHandle); SetTCB = FindTCB(TCPEntry->tct_localaddr, TCPEntry->tct_remoteaddr, (ushort)TCPEntry->tct_remoteport, (ushort)TCPEntry->tct_localport); // We found him. If he's not closing or closed, close him. if (SetTCB != NULL) { CTEGetLock(&SetTCB->tcb_lock, &TCBHandle); CTEFreeLock(&TCBTableLock, TCBHandle); // We've got him. Bump his ref. count, and call TryToCloseTCB // to mark him as closing. Then notify the upper layer client // of the disconnect. SetTCB->tcb_refcnt++; if (SetTCB->tcb_state != TCB_CLOSED && !CLOSING(SetTCB)) { SetTCB->tcb_flags |= NEED_RST; TryToCloseTCB(SetTCB, TCB_CLOSE_ABORTED, TableHandle); CTEGetLock(&SetTCB->tcb_lock, &TableHandle); if (SetTCB->tcb_state != TCB_TIME_WAIT) { // Remove him from the TCB, and notify the client. CTEFreeLock(&SetTCB->tcb_lock, TableHandle); RemoveTCBFromConn(SetTCB); NotifyOfDisc(SetTCB, NULL, TDI_CONNECTION_RESET); CTEGetLock(&SetTCB->tcb_lock, &TableHandle); } } DerefTCB(SetTCB, TableHandle); return TDI_SUCCESS; } else { CTEFreeLock(&TCBTableLock, TableHandle); return TDI_INVALID_PARAMETER; } } else return TDI_INVALID_PARAMETER; #else return TDI_INVALID_PARAMETER; #endif } if (ID->toi_class == INFO_CLASS_IMPLEMENTATION) { // We want to return implementation specific info. For now, error out. return TDI_INVALID_REQUEST; } return TDI_INVALID_REQUEST; }