//---------------------------------------------------------------------------- // // Non-network I/O support. // // Copyright (C) Microsoft Corporation, 2000-2001. // //---------------------------------------------------------------------------- #include "pch.hpp" #include #include //---------------------------------------------------------------------------- // // 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; }