Announcement

Collapse
No announcement yet.

WinAPI - Serial communications

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • WinAPI - Serial communications

    I'm trying to control COM-port with WinAPI functions. After WriteFile function call it return error code 5 (access denied). Need your help!

    Port opened successfuly.

    Code:
    handle = kernel32.CreateFileA("\\\\.\\COM" .. n_, GENERIC_READ+GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)
    Then I define (with MemoryEx) and fill structures DCB and COMMTIMEOUTS.

    Code:
    DCB.BaudRate = CBR_9600;
    DCB.ByteSize = 8;
    DCB.Parity = NOPARITY;
    DCB.StopBits = ONESTOPBIT;
    DCB.fBinary = 1;
    DCB.fOutxCtsFlow = 0;
    DCB.fOutxDsrFlow = 0;
    DCB.fDtrControl = DTR_CONTROL_DISABLE;
    DCB.fDsrSensitivity = 0;
    DCB.fNull = 0;
    DCB.fRtsControl = RTS_CONTROL_DISABLE;
    DCB.fAbortOnError = 0;
    Code:
    COMMTIMEOUTS.ReadIntervalTimeout = 10;
    COMMTIMEOUTS.ReadTotalTimeoutMultiplier = 1;
    COMMTIMEOUTS.ReadTotalTimeoutConstant = 100;
    COMMTIMEOUTS.WriteTotalTimeoutMultiplier = 0;
    COMMTIMEOUTS.WriteTotalTimeoutConstant = 0;
    After structures filled I call API-functions SetCommState, SetCommTimeouts. Both functions returns TRUE.

    Now I want to write in port some data like this:

    Code:
    local n = Table.Count(data);
    local b = MemoryEx.Allocate(4);
    local t = MemoryEx.Allocate(n);
    if (b and t) then
    	-- clearing byte-counter and buffer
    	MemoryEx.Fill(b, 4, 0, MEMEX_BYTE);
    	MemoryEx.Fill(t, n, 0, MEMEX_BYTE);
    	-- fill buffer with data
    	local c = 1;
    	repeat
    		MemoryEx.Byte(t + c - 1, data[c]);
    		c = c + 1;
    	until c > n;
    	-- write data to port
    	if (kernel32.WriteFile(handle, t, n, b, 0) == 0) then
    		local e = kernel32.GetLastError();
    		Dialog.Message("error", e);
    	end
    end
    WriteFile returns error code 5 (access denied). Please, tell what I missed in my codes?

    Thanks!

  • #2
    You're examples are incomplete so its hard to see what you are doing from the code snips you posted.

    Post the full code with all constraints or attach a project file.

    Comment


    • #3
      Hi, Shrek!

      I have compressed my code for best readability:

      Code:
      CBR_9600              = 9600;
      DTR_CONTROL_DISABLE   = 0x00;
      RTS_CONTROL_DISABLE   = 0x00;
      NOPARITY              = 0;
      ONESTOPBIT            = 0;
      GENERIC_WRITE         = 0x40000000;
      GENERIC_READ          = 0x80000000;
      OPEN_EXISTING         = 3;
      FILE_FLAG_OVERLAPPED  = 0x40000000;
      -- load winapi
      kernel32 = Library.Load("kernel32.dll", false);
      if (kernel32) then
      	-- open port
      	_port_handle = kernel32.CreateFileA("\\\\.\\COM52", GENERIC_READ + GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
      	if (_port_handle < -1 or _port_handle > 0) then
      		-- DCB structure
      		local _dcb_info_handle = MemoryEx.DefineStruct{
      		DWORD  ("DCBlength");
      		DWORD  ("BaudRate");
      		DWORD  ("fBinary");
      		DWORD  ("fParity");
      		DWORD  ("fOutxCtsFlow");
      		DWORD  ("fOutxDsrFlow");
      		DWORD  ("fDtrControl");
      		DWORD  ("fDsrSensitivity");
      		DWORD  ("fTXContinueOnXoff");
      		DWORD  ("fOutX");
      		DWORD  ("fInX");
      		DWORD  ("fErrorChar");
      		DWORD  ("fNull");
      		DWORD  ("fRtsControl");
      		DWORD  ("fAbortOnError");
      		DWORD  ("fDummy2");
      		WORD   ("wReserved");
      		WORD   ("XonLim");
      		WORD   ("XoffLim");
      		BYTE   ("ByteSize");
      		BYTE   ("Parity");
      		BYTE   ("StopBits");
      		STRING ("XonChar",   1, 1, MEMEX_ASCII);
      		STRING ("XoffChar",  1, 1, MEMEX_ASCII);
      		STRING ("ErrorChar", 1, 1, MEMEX_ASCII);
      		STRING ("EofChar",   1, 1, MEMEX_ASCII);
      		STRING ("EvtChar",   1, 1, MEMEX_ASCII);
      		WORD   ("wReserved1");
      		};
      		if (_dcb_info_handle) then
      			_dcb_pointer = MemoryEx.Allocate(MemoryEx.StructSize(_dcb_info_handle));
      			if(_dcb_pointer)then
      				_dcb_obj_handle = MemoryEx.AssignStruct(_dcb_pointer, _dcb_info_handle);
      				if (_dcb_obj_handle) then
      					-- COMMTIMEOUTS structure
      					_commtimeouts_info_handle = MemoryEx.DefineStruct{
      					DWORD  ("ReadIntervalTimeout");
      					DWORD  ("ReadTotalTimeoutMultiplier");
      					DWORD  ("ReadTotalTimeoutConstant");
      					DWORD  ("WriteTotalTimeoutMultiplier"); 
      					DWORD  ("WriteTotalTimeoutConstant");
      					};
      					if (_commtimeouts_info_handle) then
      						_commtimeouts_pointer = MemoryEx.Allocate(MemoryEx.StructSize(_commtimeouts_info_handle));
      						if(_commtimeouts_pointer)then
      							_commtimeouts_obj_handle = MemoryEx.AssignStruct(_commtimeouts_pointer, _commtimeouts_info_handle);
      							if (_commtimeouts_obj_handle) then
      								-- fill structures DCB and COMMTIMEOUTS (default values)
      								local s1 = kernel32.GetCommState(_port_handle, _dcb_pointer);
      								local s2 = kernel32.GetCommTimeouts(_port_handle, _commtimeouts_pointer);
      								if (s1 ~= 0 and s2 ~= 0) then
      									-- fill structure DCB (user values)
      									_dcb_obj_handle.BaudRate          = CBR_9600;
      									_dcb_obj_handle.fBinary           = 1;
      									_dcb_obj_handle.fParity           = NOPARITY;
      									_dcb_obj_handle.fOutxCtsFlow      = 0;
      									_dcb_obj_handle.fOutxDsrFlow      = 0;
      									_dcb_obj_handle.fDtrControl       = DTR_CONTROL_DISABLE;
      									_dcb_obj_handle.fDsrSensitivity   = 0;
      									_dcb_obj_handle.fTXContinueOnXoff = 0;
      									_dcb_obj_handle.fNull             = 0;
      									_dcb_obj_handle.fRtsControl       = RTS_CONTROL_DISABLE;
      									_dcb_obj_handle.fAbortOnError     = 0;
      									_dcb_obj_handle.ByteSize          = 8;
      									_dcb_obj_handle.Parity            = NOPARITY;
      									_dcb_obj_handle.StopBits          = ONESTOPBIT;
      									-- fill structure COMMTIMEOUTS (user values) 
      									_commtimeouts_obj_handle.ReadIntervalTimeout         = 10;
      									_commtimeouts_obj_handle.ReadTotalTimeoutMultiplier  = 1;
      									_commtimeouts_obj_handle.ReadTotalTimeoutConstant    = 100;
      									_commtimeouts_obj_handle.WriteTotalTimeoutMultiplier = 0;
      									_commtimeouts_obj_handle.WriteTotalTimeoutConstant   = 0;
      									-- set values
      									s1 = kernel32.SetCommState(_port_handle, _dcb_pointer);
      									s2 = kernel32.SetCommTimeouts(_port_handle, _commtimeouts_pointer);
      									if (s1 ~= 0 and s2 ~= 0) then
      										_data = {51, 52, 53, 54};
      										_data_bytesnumber    = Table.Count(_data);
      										_bytecounter_pointer = MemoryEx.Allocate(4); -- DWORD
      										_buffer_pointer      = MemoryEx.Allocate(_data_bytesnumber);
      										if (_bytecounter_pointer and _buffer_pointer) then
      											-- reset byte-counter
      											MemoryEx.Fill(_bytecounter_pointer, 4, 0, MEMEX_BYTE);
      											-- fill buffer
      											for c = 1, _data_bytesnumber do
      												MemoryEx.Byte(_buffer_pointer + c - 1, _data[c]);
      											end
      											-- write data
      											s1 = kernel32.WriteFile(_port_handle, _buffer_pointer, _data_bytesnumber, _bytecounter_pointer, 0);
      											if (s1 == 0) then
      												_error = kernel32.GetLastError();
      												Dialog.Message("error", _error);
      											end
      										end
      									end
      								end
      							end
      						end
      					end
      				end
      			end
      		end
      	end
      end

      Comment

      Working...
      X