Handle von CreateFile verliert gültigkeit *verzweifel*



  • Hi!

    ich spiel mich gerade mit dem ansprechen des comm ports!

    anunfürsich is das ja nicht schwer, ABER bei mir verliert der Handle nach iniger zeit seine gültigkeit!

    wenn ich das programm debug, mit CreateFile mir eine neues gültiges Handle, wenn cih jetzt ein paar sekunden verstreichen lasse (so ca 10-20 sec) und dann weiterdebugge und dann zB die Timeouts setzen will geht das nicht weil das Handle nicht mehr gültig ist!

    wie zum geier kann man das verhindern?
    *langsamverzweifelntu*

    mfg
    montolio



  • Woran glaubst du zu erknnen, dass das Handle nicht mehr gültig ist?
    Und was hat das mit MFC zu tun?



  • weil das CreateFile was mit der MFC zu tun hat glaub ich halt dass das auch was mit der MFC zu tun hat!

    dass hande nicht mehr gültig is erkenn ich daran, dass alle funktionen, die das handle benötigen um aktion auszuführen z.B. die timeouts setzen, nicht mehr funktionieren!

    das lustige is ja wenn ich das programm schnell durchlaufe und wenig zeit verstreichen lass funktioniert es ja, nur wenn zwischen CreateFile und irgendeiner anderen funktion die das handle benötigte zeit vergeht funzt niox mehr!



  • Original erstellt von Montolio:
    weil das CreateFile was mit der MFC zu tun hat

    Da liegt wohl der Trugschluss 😉

    Was sagt denn GetLastError()?

    [ Dieser Beitrag wurde am 25.03.2003 um 10:21 Uhr von MFK editiert. ]



  • GetLastError meint:

    995

    The I/O operation has been aborted because of either a thread exit or an application request.

    ERROR_OPERATION_ABORTED



  • Womöglich ein Überlauf des Empfangspuffers.

    Schau mal hier rein:
    [url]http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&safe=off&threadm=98nh3f%24uqq%2407%241%40news.t-online.com&rnum=3&prev=/groups%3Fq%3DERROR_OPERATION_ABORTED%2BSetCommTimeou ts%26hl%3Den%26lr%3D%26ie%3DUTF-8%26safe%3Doff%26selm%3D98nh3f%2524uqq%252407%25241%2540news.t-online.com%26rnum%3D3[/url]



  • danke, das wars!

    *megafreu*

    der buffer war voll und somit hat das teil gestreikt!

    *ganzdickesDANKE*



  • Hallo liebe Forianer,

    ich wünsche Euch vorab ein schönes WE und bitte, bitte erst später schlagen ob des trivialen Charakters dieses Posts. Aber der o.g. Link geht nicht mehr und Google hilft mir gar nicht.

    Schon mal vielen Dank fürs Weiterlesen!

    Im nachfolgenden Source kapselt eine Klasse CComPort als "Server" eine RS232. Der Mechanismus steckt in einer Dll. Instanzen der Klasse werden in Threads ausgeführt.

    Im nachfolgenden Source ist folgendes gewünscht:

    1. Eine Übertragung wird mit WriteCom gestartet.
    2. Wenn das Schreiben fertig ist, soll es in WriteDone weitergehen. Das klappt.
    3. WriteDone soll dann auf die Ausführung im Controller und dessen Antwort mittels ReadDone warten, um diese Antwort zu verarbeiten. Das klappt nicht.
    4. Stackende

    ReadDone hinkt immer ein Übertragung hinterher, und ich weiss nicht warum.
    Die erste Übertragung hat immer 995 (ERROR_OPERATION_ABORTED).

    Ich bin für jede Idee dankbar! Links, Brain-debugging, etc...

    Liebe Grüße

    Lars

    Debugger:

    completion write success. 0 10
    timeout
    completion read error. 995 0
    completion write success. 0 10
    completion read success. 0 10

    Source:

    // ComPort.cpp : Defines the entry point for the DLL application.
    //
    
    #include "stdafx.h"
    #include "string.h"
    #include "ComPort.h"
    
    //-----------------------------------------------------
    // mutex for access control
    HANDLE		g_hAccessCom = NULL;
    DWORD		g_dwAccessTimeout = 2000;
    char		g_szAccessName[16] = {"ComAccessMutex"};
    
    //-----------------------------------------------------
    // process id at position index in gs_tProcReg
    DWORD		g_dwProcIndex = 0;
    
    //-----------------------------------------------------
    // 
    OVERLAPPED	g_ovl = {0};
    
    //-----------------------------------------------------
    // current instance the worker is assigned to
    CComPort	*g_lpInstance = NULL;
    DWORD		g_dwComCount = 0;
    
    //-----------------------------------------------------
    // shared information
    
    #pragma data_seg(".gCom")
    
    	DWORD			gs_dwOwnerId = 0;
    	HANDLE			gs_hCom = INVALID_HANDLE_VALUE;
    	DWORD			gs_dwProcCount = 0;
    	TProcRegistry	gs_tProcReg = {0};
    
    #pragma data_seg()
    
    #pragma comment(linker, "/SECTION:.gCom,RWS")
    
    	unsigned char	g_buffer[10] = {0};
    
    //-----------------------------------------------------
    
    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
    					 )
    {
        switch (ul_reason_for_call)
    	{
    		case DLL_PROCESS_ATTACH:
    
    			if (gs_dwProcCount > (MAX_PROCS-1) ) return false;
    
    			g_hAccessCom = OpenMutex(SYNCHRONIZE,false,g_szAccessName);
    			if (!g_hAccessCom)
    			{
    				g_hAccessCom = CreateMutex(NULL,false,g_szAccessName);
    				if (!g_hAccessCom)
    				{
    					return false;
    				}
    			}
    
    			gs_dwProcCount++;
    
    			break;
    
    		case DLL_THREAD_ATTACH:
    		case DLL_THREAD_DETACH:
    
    			break;
    
    		case DLL_PROCESS_DETACH:
    
    			if (g_hAccessCom)
    			{
    				CloseHandle(g_hAccessCom);
    				g_hAccessCom = NULL;
    			}
    
    			gs_dwProcCount--;
    
    			break;
        }
        return true;
    }
    
    //*****************************************************
    // callback function is entered when WriteCom operation
    // has finished with normally or by error
    //*****************************************************
    
    VOID CALLBACK ReadDone(DWORD dwError,DWORD dwTransferred,OVERLAPPED *ovl)
    {
    	DWORD	ret = 0;
    
    	if (dwError)
    	{
    		qDebug(QString("completion read error. %1 %2").arg(dwError).arg(dwTransferred));
    		ret = CancelIo(gs_hCom);
    //		ret = ClearCommError(gs_hCom,&dwError,NULL);
    //		ret = PurgeComm(gs_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    	}
    	else
    	{ 
    		qDebug(QString("completion read success. %1 %2").arg(dwError).arg(dwTransferred));
    	}
    }
    
    VOID CALLBACK WriteDone(DWORD dwError,DWORD dwTransferred,OVERLAPPED *ovl)
    {
    	DWORD			length = dwTransferred;
    	DWORD			ret;
    
    	if (dwError)
    	{
    		qDebug(QString("completion write error. %1 %2").arg(dwError).arg(dwTransferred));
    		LeaveCom();
    	}
    	else
    	{
    		qDebug(QString("completion write success. %1 %2").arg(dwError).arg(dwTransferred));
    
    		g_ovl.Internal = 0;
    		g_ovl.InternalHigh = 0;
    		g_ovl.Offset = 0;
    		g_ovl.OffsetHigh = 0;
    		g_ovl.hEvent = NULL;
    
    		if ( !ReadFileEx(gs_hCom,(void*)g_buffer,length,&g_ovl,ReadDone) )
    		{
    			ret = GetLastError();
    		}
    
    //		SignalObjectAndWait(gs_hCom,gs_hCom,INFINITE,true);		Phänomen: Der Hint läuft, der compiler nicht ...? Alte scheisse hier!!!
    /*
    //		Reports dwTransferred correctly, but no dwError
    		if (WAIT_TIMEOUT == WaitForSingleObjectEx(gs_hCom,INFINITE,true) )
    		{
    			qDebug("timeout");
    			ret = ClearCommError(gs_hCom,&dwError,NULL);
    
    		}
    */
    //		Reports dwError correctly, but has one cycle delay
    		if ( !SleepEx(0,true) )
    		{
    			qDebug("timeout");
    			ret = CancelIo(gs_hCom);
    //			ret = ClearCommError(gs_hCom,&dwError,NULL);
    //			ret = PurgeComm(gs_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    //			ret = GetOverlappedResult(gs_hCom,&g_ovl,&dwTransferred,true);
    		}
    
    	}
    }
    
    //*****************************************************
    // process local functions
    //*****************************************************
    
    bool ReadCom(void*& buffer,DWORD & length)
    {
    
    	return true;
    }
    
    //---------------------------------------------------
    
    bool WriteCom(void* buffer,DWORD length,CComPort* instance)
    {
    	DWORD	ret;
    	HANDLE	hOwner = NULL;
    
    	if ( !EnterCom(ACCESS_TIMEOUT) )
    	{
    		return false;
    	}
    
    	// is gs_hCom in this process-scope?
    
    	if ( gs_dwOwnerId != gs_tProcReg.id[g_dwProcIndex] )	// no
    	{
    		hOwner = OpenProcess(PROCESS_DUP_HANDLE,false,gs_dwOwnerId);
    
    		if (!hOwner)		
    		{
    			LeaveCom();
    			return false;
    		}
    		else
    		{
    			// try to transfer gs_hCom into this process
    			if ( !DuplicateHandle(	hOwner,
    									gs_hCom,
    									GetCurrentProcess(),
    									&gs_hCom,
    									DUPLICATE_SAME_ACCESS,
    									false,
    									DUPLICATE_CLOSE_SOURCE) )
    			{
    				CloseHandle(hOwner);
    				LeaveCom();
    				return false;
    			}
    			CloseHandle(hOwner);
    		}
    
    		// now it is
    		gs_dwOwnerId = gs_tProcReg.id[g_dwProcIndex];
    	}
    
    	g_lpInstance = instance;
    
    	g_ovl.Internal = 0;
    	g_ovl.InternalHigh = 0;
    	g_ovl.Offset = 0;
    	g_ovl.OffsetHigh = 0;
    	g_ovl.hEvent = NULL;
    
    	if ( !WriteFileEx(gs_hCom,buffer,length,&g_ovl,WriteDone) )
    	{
    		ret = GetLastError();
    		LeaveCom();
    		return false;
    	}
    
    	FlushFileBuffers(gs_hCom);
    
    	if ( !SleepEx(0,true))
    	{
    		qDebug("timeout write");
    	}
    
    	return true;
    }
    //------------------------------------------------------
    // Function inserts proc-id into registry, if id > 0. 
    // CCom-ctor calls function with id > 0.
    //
    // When id == 0, the function searches an valid id (>0), 
    // duplicates gs_hCom into the process' scope and 
    // sets this id as the new owner of gs_hCom.
    // CCom-dtor call this function with id = 0, when the last
    // instance of CCom closes in a process.
    //
    // Function must be encapsulated by EnterCom()/LeaveCom()!
    
    bool RestoreCom(DWORD id)
    {
    	HANDLE newOwner = NULL;
    	DWORD i;
    
    	if (id)		// ctor
    	{
    		for (i=0;i<MAX_PROCS;i++)
    		{
    			if (!gs_tProcReg.id[i])	// a value of "0" (zero) indicates a free location
    			{
    				gs_tProcReg.id[i] = id;
    				g_dwProcIndex = i;
    				break;
    			}
    		}
    	}
    	else		// dtor
    	{
    		for (i=0;i<MAX_PROCS;i++)	//find any valid id that is not my id
    		{
    			if ( gs_tProcReg.id[i] && (i != g_dwProcIndex) )
    			{
    				newOwner = OpenProcess(PROCESS_DUP_HANDLE,false,gs_tProcReg.id[i]);
    
    				if (!newOwner)
    				{
    					return false;
    				}
    
    				if ( !DuplicateHandle(	GetCurrentProcess(),
    										gs_hCom,
    										newOwner,
    										&gs_hCom,
    										DUPLICATE_SAME_ACCESS,
    										false,
    										DUPLICATE_CLOSE_SOURCE) )
    				{
    					CloseHandle(newOwner);
    					return false;
    				}
    				CloseHandle(newOwner);
    
    				gs_dwOwnerId = gs_tProcReg.id[i];
    				gs_tProcReg.id[g_dwProcIndex] = 0;
    
    				break;
    			}
    		}
    	}
    
    	if (i == MAX_PROCS)
    	{
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    
    //------------------------------------------------------
    // function does process global, initial settings. 
    //
    // EnterCom()/LeaveCom() must be called before/after 
    // calling this function!
    
    bool OpenCom(void)
    {
    	COMMCONFIG		cc;
    	COMMTIMEOUTS	cto;
    //	COMMPROP		cp;			//	only needed for old chips. 16450 uart or higher assumed
    	char			com[10] = {""};
    	DWORD			dwSize;
    	DWORD			dwError;
    	DWORD			ret = 0;
    	int				i;
    
    	// determine, if rs232-port is available and get handle
    	for (i=MIN_COM_PORT;i<=MAX_COM_PORT;i++)
    	{
    		wsprintf(com,"\\\\.\\com%d",i);
    
    		gs_hCom = CreateFile(	com,
    								GENERIC_READ | GENERIC_WRITE,
    								0,
    								NULL,
    								OPEN_EXISTING,
    								FILE_FLAG_OVERLAPPED,
    								NULL);
    
    		if (gs_hCom != INVALID_HANDLE_VALUE)
    		{
    			cc.dwSize = sizeof(COMMCONFIG);
    			cc.dcb.DCBlength = sizeof(DCB);
    			if (!GetCommConfig(gs_hCom,&cc,&dwSize))
    			{
    				return false;
    			}
    
    			if (cc.dwProviderSubType == PST_RS232)	
    			{
    				// analyze COMMPROP cp here, if old uart is used
    				break;		//ok, assume handle is RS232 with all needed features
    			}
    		}
    	}
    
    	// no RS232 port found?
    	if (gs_hCom == INVALID_HANDLE_VALUE)	
    	{
    		return false;
    	}
    
    	//COMMCONFIG settings
    	cc.dcb.BaudRate = CBR_9600;
    	cc.dcb.ByteSize = 8;
    	cc.dcb.EofChar = '\0';
    	cc.dcb.ErrorChar = '\0';
    	cc.dcb.EvtChar = '\0';
    	cc.dcb.fAbortOnError = true;
    	cc.dcb.fBinary = true;
    	cc.dcb.fDsrSensitivity = false;
    	cc.dcb.fDtrControl = DTR_CONTROL_DISABLE;
    	cc.dcb.fErrorChar = false;
    	cc.dcb.fInX = false;
    	cc.dcb.fNull = false;
    	cc.dcb.fOutX = false;
    	cc.dcb.fOutxCtsFlow = false;
    	cc.dcb.fOutxDsrFlow = false;
    	cc.dcb.fParity = false;
    	cc.dcb.fRtsControl = RTS_CONTROL_DISABLE;
    	cc.dcb.fTXContinueOnXoff = true;
    	cc.dcb.Parity = NOPARITY;
    	cc.dcb.StopBits = ONESTOPBIT;
    	cc.dcb.XoffChar = '\0';
    	cc.dcb.XoffLim = 0;
    	cc.dcb.XonChar = '\0';
    	cc.dcb.XonLim = 0;
    
    	if (!SetCommConfig(gs_hCom,&cc,sizeof(COMMCONFIG)))
    	{
    		return false;
    	}
    
    	//COMMTIMEOUTS settings
    	cto.ReadIntervalTimeout = (DWORD)( (1/cc.dcb.BaudRate) * 10 + 2);	
    	cto.ReadTotalTimeoutConstant = 100;
    	cto.ReadTotalTimeoutMultiplier = 100;
    	cto.WriteTotalTimeoutConstant = 100;
    	cto.WriteTotalTimeoutMultiplier = 100;
    
    	if (!SetCommTimeouts(gs_hCom,&cto))
    	{
    		return false;
    	}
    
    	//abort pending communications and clean buffers
    	if (!PurgeComm(gs_hCom, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR))
    	{
    		return false;
    	}
    /*
    	// reset port errors
    	if ( !CancelIo(gs_hCom) )
    	{
    		return false;
    	}
    
    	if ( !ClearCommError(gs_hCom,&dwError,NULL) )
    	{
    		return false;
    	}
    */
    	// the process calling this function gets initial ownership and
    	// provides process-id for duplicating gs_hCom to other process-scopes
    	gs_dwOwnerId = gs_tProcReg.id[g_dwProcIndex];	
    
    	// all successfully done
    	return true;
    }
    
    //---------------------------------------------------
    
    void CloseCom(void)
    {
    	if (gs_hCom != INVALID_HANDLE_VALUE)
    	{
    		CloseHandle(gs_hCom);
    		gs_hCom = INVALID_HANDLE_VALUE;
    	}
    }
    
    //---------------------------------------------------
    // functions enter or leave the mutex g_hAccessCom
    
    bool EnterCom(DWORD timeout)
    {
    	if (WAIT_TIMEOUT == WaitForSingleObject(g_hAccessCom,timeout) )
    	{
    		return false;
    	}
    	else
    	{
    		return true;
    	}
    }
    
    bool LeaveCom(void)
    {
    	return ReleaseMutex(g_hAccessCom);
    }
    
    //******************************************************
    // interfaceclass CComPort encapsulates local functions
    //******************************************************
    
    CComPort::CComPort(void)
    { 
    	// if this instance is the first instance generated in process
    	if (!g_dwComCount)
    	{
    		// get procid and save it in registration
    		if ( EnterCom(ACCESS_TIMEOUT) )
    		{
    			RestoreCom( GetCurrentProcessId() );
    
    			LeaveCom();
    		}
    	}
    
    	//Increment instance counter	
    	g_dwComCount++;		
    
    	// if this instance was generated by the first dll-attaching process
    	if ( EnterCom(ACCESS_TIMEOUT) )
    	{
    		if ( (gs_dwProcCount<=1) && (gs_hCom == INVALID_HANDLE_VALUE) ) 
    		{
    			OpenCom();
    		}
    
    		LeaveCom();
    	}
    }
    
    //-----------------------------------------------------
    
    CComPort::~CComPort(void)
    {
    	g_dwComCount--;	//Decrement instance counter
    
    	if (!g_dwComCount)	// was last instance in process?
    	{
    		if ( EnterCom(ACCESS_TIMEOUT) )
    		{
    			if (gs_dwProcCount == 1)	//was last process attached to dll?
    			{
    				CloseCom();
    			}
    			else
    			{
    				//not the last process but the owner of gs_hCom?
    				if (gs_dwOwnerId == gs_tProcReg.id[g_dwProcIndex] )	
    				{
    					RestoreCom(0);	// move gs_hCom to other process
    				}
    			}
    			LeaveCom();
    		}
    	}
    }
    //-----------------------------------------------------
    
    bool CComPort::setCurrent(unsigned __int32 current)
    {
    
    	return true;
    }
    
    //-----------------------------------------------------
    
    unsigned __int32 CComPort::current(void)
    {
    	unsigned __int32 curr = 0;
    
    	return curr;
    }
    
    //-----------------------------------------------------
    
    bool CComPort::setVoltage(unsigned __int32 voltage)
    {
    
    	return true;
    }
    
    //-----------------------------------------------------
    
    unsigned __int32 CComPort::voltage(void)
    {
    	unsigned __int32 volt = 0;
    
    	return volt;
    }
    
    //-----------------------------------------------------
    
    unsigned __int32 CComPort::status(void)
    {
    	unsigned __int32 state = 0;
    
    	return state;
    }
    
    //-----------------------------------------------------
    
    unsigned __int32 CComPort::warmup(void)
    {
    	unsigned __int32 step = 0;
    
    	return step;
    }
    
    //-----------------------------------------------------
    
    unsigned __int32 CComPort::conditioning(void)
    {
    	unsigned __int32 step = 0;
    
    	return step;
    }
    
    //-----------------------------------------------------
    
    QString CComPort::version(void)
    {
    	QString	ver = "";
    
    	return ver;
    }
    
    //-----------------------------------------------------
    
    bool CComPort::xray(bool on)
    {
    
    	return true;
    }
    
    //-----------------------------------------------------
    
    unsigned __int8 CComPort::readMem(unsigned __int16 address)
    {
    	unsigned __int8 value = 0;
    
    	return value;
    }
    
    //-----------------------------------------------------
    
    bool CComPort::writeMem(unsigned __int16 address,unsigned __int8 value)
    {
    
    	return true;
    }
    
    //-----------------------------------------------------
    
    bool CComPort::testWrite(unsigned char * buffer,int size)
    {
    	return WriteCom((void*) buffer,(DWORD) size,this);
    
    }
    

Anmelden zum Antworten