Ich stell mal den Part mit Senden da rein. Zur Erläuterung: das Open & close ist einfach abgeschrieben (Comtools), ist ja für I2C auch ziemlich egal.
Alle Calls haben also als Argument daher immer die Nummer des Handles. Die Windows-Port-Funktionen werdet ihr ja eh kennen.

Code:
#define 	MAX_COM_PORTS	32

#define SCL_ON		MS_CTS_ON
#define SDA_ON		MS_DSR_ON

static HANDLE	hComFile[MAX_COM_PORTS];
static BOOL	bIsOpen	[MAX_COM_PORTS];
static DCB	sDcb	[MAX_COM_PORTS];
static int	iMsk	[MAX_COM_PORTS];

//*****************************************************************************
//*
//*		ComOpen
//*
//*****************************************************************************
//	Öffnet eine serielle Verbindung
//	Nr			: Ist die Nummer des Com-Ports (0=COM1 1=COM2 ...)
//	Baud		: Ist die Bautrate
//	Parity		: 0 = kein Parity Bit
//			  1 = gerade
//			  2 = ungerade
//			  3	= immer 0
//			  4 = immer 1
//	Stopbits	: 0 = Ein Stopbit
//			  1 = Ein/einhalb Stopbits	
//			  2 = Zwei Stopbits
//	Bits		: 0 = 7 Datenbits
//			  1 = 8 Datenbits
//			  7 = 7 Datenbits
//			  8 = 8 Datenbits			
//	Ergibt 1 wenn eine Schnittstelle geöffnet wurde 
int		CRtport::CRtPortOpen	(unsigned Nr,int Baud,int Parity,int Stopbits,int Databits)
{
static const int	iPMode[]	= {NOPARITY, EVENPARITY, ODDPARITY, SPACEPARITY, MARKPARITY};
static const int	iSMode[]	= {ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS};
char			cName[]="\\\\.\\COM1";
HANDLE			hFile;
COMMTIMEOUTS		sTo;

	if	(Nr >= MAX_COM_PORTS)	return 0;
	if	(bIsOpen[Nr])		return 0;
	cName[7]='1' + Nr;
	hFile	= CreateFile	(cName,	GENERIC_READ|GENERIC_WRITE,0,0,
					OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
	if	(hFile==INVALID_HANDLE_VALUE)
	{
		hFile=0;
		return 0;
	}
	if	(Databits == 7)	
		Databits	= 0;
	memset(&sDcb[Nr],0,sizeof(sDcb[Nr]));
	sDcb[Nr].DCBlength	= sizeof(sDcb[Nr]);
	sDcb[Nr].BaudRate     	= Baud;
	sDcb[Nr].fParity      	= (Parity!=0)? TRUE:FALSE;
	sDcb[Nr].fBinary      	= TRUE;
	sDcb[Nr].Parity       	= iPMode[Parity];
	sDcb[Nr].StopBits     	= ONESTOPBIT;
	sDcb[Nr].fOutxCtsFlow 	= FALSE;
	sDcb[Nr].fOutxDsrFlow 	= FALSE; 
	sDcb[Nr].fDtrControl	= DTR_CONTROL_ENABLE;
	sDcb[Nr].fRtsControl	= RTS_CONTROL_ENABLE;
	sDcb[Nr].fDsrSensitivity= FALSE;
	sDcb[Nr].fAbortOnError	= FALSE;
	sDcb[Nr].ByteSize     	= (Databits)? 8:7;
	if	(!SetCommState(hFile,&sDcb[Nr]))
	{
		CloseHandle(hFile);
		return 0;
	}
	sTo.ReadIntervalTimeout	   = MAXDWORD; 		// 0 ms Read-Timeout
	sTo.ReadTotalTimeoutMultiplier = 0; 
	sTo.ReadTotalTimeoutConstant   = 0; 
	sTo.WriteTotalTimeoutMultiplier= 1;		// 1*2 ms Write Timeout
	sTo.WriteTotalTimeoutConstant  = 2;
	if	(!SetCommTimeouts((HANDLE)hFile,&sTo))
	{
		CloseHandle(hFile);
		return 0;
	}
	hComFile[Nr]	= hFile;
	bIsOpen [Nr]	= TRUE;
	return 1;
}

//*****************************************************************************
//*
//*		ComClose
//*
//*****************************************************************************
int	CRtport::CRtPortClose		(unsigned Nr)
{
	if	(Nr >= MAX_COM_PORTS)	return 0;
	if	(!bIsOpen[Nr])			return 0;
	CloseHandle(hComFile[Nr]);
	hComFile[Nr]=0;
	bIsOpen [Nr]=FALSE;
	return 1;
}
//*****************************************************************************
int	CRtport::CRtPortI2CStop		(unsigned Nr)
{
	if (CRtPortCheckNr(Nr))		return(CRtPortStopNr(Nr));
	else						return(0);
}
//*****************************************************************************
//*
//*		Send Bytes
//*
//*****************************************************************************
int	CRtport::CRtPortCheckNr		(unsigned Nr)
{
	if	(Nr >= MAX_COM_PORTS)			return 0;
	if	(!bIsOpen[Nr])				return 0;
	GetCommState(hComFile[Nr],&sDcb[Nr]);
	return(1);
}
//*****************************************************************************
int	CRtport::CRtPortGetLine	(unsigned Nr)
{
int	iModem	= 0;
	if (!CRtPortCheckNr(Nr))			return 0;
	if (!GetCommModemStatus(hComFile[Nr], (unsigned long*)&iModem))
		return 0;
	return(iModem);
}
//*****************************************************************************
//*
//*		Set DRS CTS
//*
//*****************************************************************************
int		CRtport::CRtPortSCLNr		(unsigned Nr, int Val)
{
	if 	(Val)	sDcb[Nr].fRtsControl	= RTS_CONTROL_ENABLE;
	else		sDcb[Nr].fRtsControl	= RTS_CONTROL_DISABLE;
	return (SetCommState(hComFile[Nr],&sDcb[Nr]));
}
//*****************************************************************************
int		CRtport::CRtPortSDANr		(unsigned Nr, int Val)
{
	if	(Val)	sDcb[Nr].fDtrControl	= DTR_CONTROL_ENABLE;
	else		sDcb[Nr].fDtrControl	= DTR_CONTROL_DISABLE;
	return (SetCommState(hComFile[Nr],&sDcb[Nr]));
}
//*****************************************************************************
static void _delay(void)
{
int	iX;
	for (iX = 0; iX < 255;iX++)
	{
	}
}
//*****************************************************************************
int		CRtport::CRtPortStopNr		(unsigned Nr)
{
	CRtPortSDANr(Nr, 0);
	_delay();
	CRtPortSCLNr(Nr, 1);
	_delay();
	CRtPortSDANr(Nr, 1);
	_delay();
	return (1);
}
//*****************************************************************************
int		CRtport::CRtPortStartNr		(unsigned Nr)
{
	CRtPortSDANr(Nr, 0);
	_delay();
	CRtPortSCLNr(Nr, 0);
	_delay();
	return (1);
}
//*****************************************************************************
int		CRtport::CRtPortTickNr		(unsigned Nr)
{
int	iNew;
int	iAck;
	CRtPortSCLNr	(Nr, 1);
	do {	GetCommModemStatus(hComFile[Nr], (unsigned long*)&iNew);
	} while (!(iNew & SCL_ON));
	if (iNew & SDA_ON)	iAck = 1;
	else			iAck = 0;
	_delay();
	CRtPortSCLNr	(Nr, 0);
	_delay();
	return(iAck);
}
//*****************************************************************************
int	CRtport::CRtPortI2CSendByte	(unsigned Nr, int Val)
{
int	iCnt;
int	iByte	= Val;
	for (iCnt = 0; iCnt < 8; iCnt++)
	{
		if (iByte & 0x80)	CRtPortSDANr(Nr, 1);
		else			CRtPortSDANr(Nr, 0);
		_delay();
		CRtPortTickNr (Nr);
		iByte <<= 1;
	}
	CRtPortSDANr(Nr, 1);
	_delay();
	return(CRtPortTickNr (Nr));
}
//*****************************************************************************
int	CRtport::CRtPortI2CStart		(unsigned Nr)
{
int	iNew	= 0;
	if (!CRtPortCheckNr(Nr))		return 0;
	CRtPortSDANr(Nr, 1);
	CRtPortSCLNr(Nr, 1);
	do {	GetCommModemStatus(hComFile[Nr], (unsigned long*)&iNew);
	} while (!(iNew & SCL_ON) || !(iNew & SDA_ON));
	return(CRtPortStartNr(Nr));
}
Das Senden hat im Prinzip ja geklappt.

Ich stell' dann noch die Versuche des "sniffens" rein, zur allgemeinen Erheiterung. ICh muß mir das aber nochmal durchlesen, damit ich mich wenigsten selbst auskenne, was ich da herumgewurstelt habe.