windows-nt/Source/XPSP1/NT/base/headless/tcsrv/server/utils.c
2020-09-26 16:20:57 +08:00

328 lines
7.4 KiB
C

/*
* Copyright (c) Microsoft Corporation
*
* Module Name :
* utils.c
*
* Some utility functions used by the service.
*
* Sadagopan Rajaram -- Oct 18, 1999
*
*/
#include "tcsrv.h"
#include <ntddser.h>
#include "tcsrvc.h"
#include "proto.h"
PCOM_PORT_INFO
FindDevice(
LPTSTR device,
int *pIndex
)
/*++
Searches through the global list and returns the COM port with the
correct name
Remember that the shared global variables are not locked during this
function call
--*/
{
PCOM_PORT_INFO pTemp;
int i=ComPorts-1;
pTemp = ComPortInfo;
while(pTemp){
if(!((_tcscmp(pTemp->Device.Buffer,device)) &&
(_tcscmp(pTemp->Name.Buffer, device))))
break;
pTemp = pTemp->Next;
i--;
}
*pIndex = i;
return pTemp;
}
LONG
GetNextParameter(
HKEY hKey,
DWORD dwIndex,
PHKEY pChild,
LPTSTR *Name
)
/*++
Gets the name of the Com Port. It is a user defined name and has nothing
to do with the device name in NT.
Return -
A filled in Com port info, else NULL if end of Parameters is reached.
--*/
{
LONG RetVal;
// Registry names cannot be longer than 256 characters.
TCHAR lpName[MAX_REGISTRY_NAME_SIZE];
DWORD lpcName;
FILETIME lpftLastWriteTime;
lpcName = MAX_REGISTRY_NAME_SIZE;
RetVal = RegEnumKeyEx(hKey,
dwIndex,
lpName,
&lpcName,
NULL,
NULL,
NULL,
&lpftLastWriteTime
);
if(RetVal != ERROR_SUCCESS){
RegCloseKey(hKey);
return RetVal;
}
*Name = (LPTSTR) TCAllocate(sizeof(TCHAR)*(lpcName+1),"Registry key");
if((*Name) == NULL){
RegCloseKey(hKey);
return(ERROR_NOT_ENOUGH_MEMORY);
}
_tcscpy((*Name),lpName);
RetVal= RegOpenKeyEx(hKey,
lpName, // subkey name
0, // reserved
KEY_ALL_ACCESS, // security access mask
pChild
);
if(RetVal != ERROR_SUCCESS){
RegCloseKey(hKey);
}
return RetVal;
}
LONG
GetNameOfDeviceFromRegistry(
HKEY hKey,
LPTSTR *device
)
/*++
Gets the NT device Name. If there is no device name, it is an error.
Return-
Device Name like L"\\device\\serial0"
--*/
{
LONG RetVal;
DWORD lpType=0;
LPTSTR lpData = NULL;
DWORD lpcbData=0;
RetVal = RegQueryValueEx(hKey,
_T("Device"),
NULL,
&lpType,
(LPBYTE)lpData,
&lpcbData
);
if((RetVal != ERROR_SUCCESS)
&&(RetVal != ERROR_MORE_DATA)){
RegCloseKey(hKey);
return RetVal;
}
lpData = (LPTSTR) TCAllocate(lpcbData, "Device Name");
if(lpData == NULL){
RegCloseKey(hKey);
return ERROR_NOT_ENOUGH_MEMORY;
}
RetVal = RegQueryValueEx(hKey,
_T("Device"),
NULL,
&lpType,
(LPBYTE)lpData,
&lpcbData
);
if(RetVal != ERROR_SUCCESS){
RegCloseKey(hKey);
TCFree(lpData);
return RetVal;
}
*device = lpData;
return ERROR_SUCCESS;
}
PCOM_PORT_INFO
GetComPortParameters(
HKEY hKey
)
{
PCOM_PORT_INFO pComPortInfo;
DWORD dwordsize;
ULONG RetVal;
DWORD data;
dwordsize = sizeof(DWORD);
pComPortInfo = (PCOM_PORT_INFO)TCAllocate(sizeof(COM_PORT_INFO),"Com Port Data");
if(pComPortInfo== NULL){
RegCloseKey(hKey);
return NULL;
}
data = DEFAULT_BAUD_RATE;
RetVal = RegQueryValueEx(hKey,
_T("Baud Rate"),
NULL,
NULL,
(LPBYTE) &data,
&(dwordsize)
);
pComPortInfo->BaudRate = (ULONG) data;
data = STOP_BIT_1;
RetVal = RegQueryValueEx(hKey,
_T("Stop Bits"),
NULL,
NULL,
(LPBYTE) &data,
&(dwordsize)
);
pComPortInfo->StopBits = (UCHAR) data;
data = NO_PARITY;
RetVal = RegQueryValueEx(hKey,
_T("Stop Bits"),
NULL,
NULL,
(LPBYTE) &data,
&(dwordsize)
);
pComPortInfo->Parity = (UCHAR) data;
data = SERIAL_DATABITS_8;
RetVal = RegQueryValueEx(hKey,
_T("Word Length"),
NULL,
NULL,
(LPBYTE) &data,
&(dwordsize)
);
pComPortInfo->WordLength = (UCHAR) data;
return pComPortInfo;
}
VOID
FreeComPortInfo(
PCOM_PORT_INFO pTemp
)
{
if(pTemp == NULL) return;
if (pTemp->Device.Buffer) {
TCFree(pTemp->Device.Buffer);
}
if(pTemp->Name.Buffer){
TCFree(pTemp->Name.Buffer);
}
NtClose(pTemp->Events[1]);
NtClose(pTemp->Events[2]);
NtClose(pTemp->Events[3]);
NtClose(pTemp->TerminateEvent);
NtClose(pTemp->WriteOverlapped.hEvent);
DeleteCriticalSection(&(pTemp->Mutex));
TCFree(pTemp);
return;
}
VOID Enqueue(
PCOM_PORT_INFO pComPortInfo
)
{
int i,size,j,k;
size = (int) pComPortInfo->Overlapped.InternalHigh;
j = pComPortInfo->Tail;
k = pComPortInfo->Head;
for(i=0;i<size;i++){
(pComPortInfo->Queue)[j] = (pComPortInfo->Buffer)[i];
j = (j+1)% MAX_QUEUE_SIZE;
if(k==j){
k = (k+1)%MAX_QUEUE_SIZE;
}
}
pComPortInfo->Head = k;
pComPortInfo->Tail =j;
return;
}
int GetBufferInfo(
PCONNECTION_INFO pConnection,
PCOM_PORT_INFO pComPortInfo
)
{
int i,size;
int Status;
size = 0;
for(i=pComPortInfo->Head; (i != pComPortInfo->Tail ); i=(i+1)%(MAX_QUEUE_SIZE)){
(pConnection->buffer)[size] = (pComPortInfo->Queue)[i];
size++;
if(size == MAX_BUFFER_SIZE){
Status=send(pConnection->Socket, pConnection->buffer, size, 0);
if(Status == SOCKET_ERROR){
return Status;
}
size = 0;
}
}
if(size){
Status = send(pConnection->Socket, pConnection->buffer, size, 0);
if(Status == SOCKET_ERROR){
return Status;
}
}
return 0;
}
LONG
TCLock(
PHANDLE lock
)
{
LONG RetVal;
(*lock) = CreateMutex(NULL,
FALSE,
TCSERV_MUTEX_NAME
);
if ((*lock)) {
RetVal = WaitForSingleObject(*lock,INFINITE);
if (RetVal == WAIT_FAILED) {
return GetLastError();
}
else{
return ERROR_SUCCESS;
}
}
else{
return GetLastError();
}
}
VOID
TCUnlock(
HANDLE lock
)
{
if (lock) {
ReleaseMutex(lock);
CloseHandle(lock);
}
return;
}