|
|
//----------------------------------------------------------------------------
//
// Non-network I/O support.
//
// Copyright (C) Microsoft Corporation, 2000-2001.
//
//----------------------------------------------------------------------------
#include "pch.hpp"
#include <kdbg1394.h>
#include <ntdd1394.h>
//----------------------------------------------------------------------------
//
// COM.
//
//----------------------------------------------------------------------------
HRESULT CreateOverlappedPair(LPOVERLAPPED Read, LPOVERLAPPED Write) { ZeroMemory(Read, sizeof(*Read)); ZeroMemory(Write, sizeof(*Write)); Read->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (Read->hEvent == NULL) { return WIN32_LAST_STATUS(); }
Write->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (Write->hEvent == NULL) { CloseHandle(Read->hEvent); return WIN32_LAST_STATUS(); }
return S_OK; }
BOOL ComPortRead(HANDLE Port, PVOID Buffer, ULONG Len, PULONG Done, LPOVERLAPPED Olap) { BOOL Status;
Status = ReadFile(Port, Buffer, Len, Done, Olap); if (!Status) { if (GetLastError() == ERROR_IO_PENDING) { Status = GetOverlappedResult(Port, Olap, Done, TRUE); } else { DWORD TrashErr; COMSTAT TrashStat; // Device could be locked up. Clear it just in case.
ClearCommError(Port, &TrashErr, &TrashStat); } }
return Status; }
BOOL ComPortWrite(HANDLE Port, PVOID Buffer, ULONG Len, PULONG Done, LPOVERLAPPED Olap) { BOOL Status;
Status = WriteFile(Port, Buffer, Len, Done, Olap); if (!Status) { if (GetLastError() == ERROR_IO_PENDING) { Status = GetOverlappedResult(Port, Olap, Done, TRUE); } else { DWORD TrashErr; COMSTAT TrashStat; // Device could be locked up. Clear it just in case.
ClearCommError(Port, &TrashErr, &TrashStat); } }
return Status; }
void SetComPortName(PCSTR Name, PSTR Buffer) { if (*Name == 'c' || *Name == 'C') { strcpy(Buffer, "\\\\.\\"); strcpy(Buffer + 4, Name); } else if (*Name >= '0' && *Name <= '9') { PCSTR Scan = Name + 1; while (*Scan >= '0' && *Scan <= '9') { Scan++; } if (*Scan == 0) { // The name was all digits so assume it's
// a plain com port number.
#ifndef NT_NATIVE
strcpy(Buffer, "\\\\.\\com"); #else
strcpy(Buffer, "\\Device\\Serial"); #endif
strcat(Buffer, Name); } else { strcpy(Buffer, Name); } } else { strcpy(Buffer, Name); } }
ULONG SelectComPortBaud(ULONG NewRate) { #define NUM_RATES 4
static DWORD s_Rates[NUM_RATES] = {19200, 38400, 57600, 115200}; static DWORD s_CurRate = NUM_RATES;
DWORD i;
if (NewRate > 0) { for (i = 0; NewRate > s_Rates[i] && i < NUM_RATES - 1; i++) { // Empty.
} s_CurRate = (NewRate < s_Rates[i]) ? i : i + 1; } else { s_CurRate++; }
if (s_CurRate >= NUM_RATES) { s_CurRate = 0; }
return s_Rates[s_CurRate]; }
HRESULT SetComPortBaud(HANDLE Port, ULONG NewRate, PULONG RateSet) { ULONG OldRate; DCB LocalDcb;
if (Port == NULL) { return E_FAIL; }
if (!GetCommState(Port, &LocalDcb)) { return WIN32_LAST_STATUS(); }
OldRate = LocalDcb.BaudRate;
if (!NewRate) { NewRate = SelectComPortBaud(OldRate); }
LocalDcb.BaudRate = NewRate; LocalDcb.ByteSize = 8; LocalDcb.Parity = NOPARITY; LocalDcb.StopBits = ONESTOPBIT; LocalDcb.fDtrControl = DTR_CONTROL_ENABLE; LocalDcb.fRtsControl = RTS_CONTROL_ENABLE; LocalDcb.fBinary = TRUE; LocalDcb.fOutxCtsFlow = FALSE; LocalDcb.fOutxDsrFlow = FALSE; LocalDcb.fOutX = FALSE; LocalDcb.fInX = FALSE;
if (!SetCommState(Port, &LocalDcb)) { return WIN32_LAST_STATUS(); }
*RateSet = NewRate; return S_OK; }
HRESULT OpenComPort(PSTR Port, ULONG BaudRate, ULONG Timeout, PHANDLE Handle, PULONG BaudSet) { HANDLE ComHandle;
#ifndef NT_NATIVE
ComHandle = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); #else
ComHandle = NtNativeCreateFileA(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL, FALSE); #endif
if (ComHandle == INVALID_HANDLE_VALUE) { return WIN32_LAST_STATUS(); } if (!SetupComm(ComHandle, 4096, 4096)) { CloseHandle(ComHandle); return WIN32_LAST_STATUS(); }
HRESULT Status; if ((Status = SetComPortBaud(ComHandle, BaudRate, BaudSet)) != S_OK) { CloseHandle(ComHandle); return Status; }
COMMTIMEOUTS To; if (Timeout) { To.ReadIntervalTimeout = 0; To.ReadTotalTimeoutMultiplier = 0; To.ReadTotalTimeoutConstant = Timeout; To.WriteTotalTimeoutMultiplier = 0; To.WriteTotalTimeoutConstant = Timeout; } else { To.ReadIntervalTimeout = 0; To.ReadTotalTimeoutMultiplier = 0xffffffff; To.ReadTotalTimeoutConstant = 0xffffffff; To.WriteTotalTimeoutMultiplier = 0xffffffff; To.WriteTotalTimeoutConstant = 0xffffffff; }
if (!SetCommTimeouts(ComHandle, &To)) { CloseHandle(ComHandle); return WIN32_LAST_STATUS(); }
*Handle = ComHandle; return S_OK; }
//----------------------------------------------------------------------------
//
// 1394.
//
//----------------------------------------------------------------------------
HRESULT Create1394Channel(ULONG Channel, PSTR Name, PHANDLE Handle) { char BusName[] = "\\\\.\\1394BUS0"; HANDLE hDevice; //
// we need to make sure the 1394vdbg driver is up and loaded.
// send the ADD_DEVICE ioctl to eject the VDO
// Assume one 1394 host controller...
//
hDevice = CreateFile(BusName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hDevice != INVALID_HANDLE_VALUE) { char DeviceId[] = "VIRTUAL_HOST_DEBUGGER"; ULONG ulStrLen; PIEEE1394_API_REQUEST pApiReq; PIEEE1394_VDEV_PNP_REQUEST pDevPnpReq; DWORD dwBytesRet; ulStrLen = strlen(DeviceId) + 1; pApiReq = (PIEEE1394_API_REQUEST) malloc(sizeof(IEEE1394_API_REQUEST) + ulStrLen); if (pApiReq == NULL) { CloseHandle(hDevice); return E_OUTOFMEMORY; }
pApiReq->RequestNumber = IEEE1394_API_ADD_VIRTUAL_DEVICE; pApiReq->Flags = IEEE1394_REQUEST_FLAG_PERSISTENT | IEEE1394_REQUEST_FLAG_USE_LOCAL_HOST_EUI;
pDevPnpReq = &pApiReq->u.RemoveVirtualDevice;
pDevPnpReq->fulFlags = 0;
pDevPnpReq->Reserved = 0; pDevPnpReq->InstanceId.QuadPart = 0; strncpy((PSZ)&pDevPnpReq->DeviceId, DeviceId, ulStrLen);
// Failure of this call is not fatal.
DeviceIoControl( hDevice, IOCTL_IEEE1394_API_REQUEST, pApiReq, sizeof(IEEE1394_API_REQUEST)+ulStrLen, NULL, 0, &dwBytesRet, NULL );
if (pApiReq) { free(pApiReq); } CloseHandle(hDevice); } else { return WIN32_LAST_STATUS(); }
return Open1394Channel(Channel, Name, Handle); }
HRESULT Open1394Channel(ULONG Channel, PSTR Name, PHANDLE Handle) { sprintf(Name, "\\\\.\\DBG1394_CHANNEL%02d", Channel); *Handle = CreateFile(Name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (*Handle == INVALID_HANDLE_VALUE) { return WIN32_LAST_STATUS(); }
return S_OK; }
|