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 hatDa 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. StackendeReadDone 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 10Source:
// 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); }