784 lines
20 KiB
C
784 lines
20 KiB
C
// Copyright (c) 1998-1999 Microsoft Corporation
|
||
/******************************************************************************
|
||
*
|
||
* CHGPORT.C
|
||
*
|
||
* Change serial port mapping.
|
||
*
|
||
*
|
||
*
|
||
*******************************************************************************/
|
||
|
||
#include <nt.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
#include <windows.h>
|
||
#include <winstaw.h>
|
||
#include <assert.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <utilsub.h>
|
||
#include <string.h>
|
||
#include <printfoa.h>
|
||
#include <locale.h>
|
||
|
||
#include "chgport.h"
|
||
|
||
/*
|
||
* Global Data
|
||
*/
|
||
WCHAR user_string[MAX_IDS_LEN+1]; // parsed user input
|
||
USHORT help_flag = FALSE; // User wants help
|
||
USHORT fDelete = FALSE; // delete mapped port
|
||
USHORT fquery = FALSE; // query the mapped ports
|
||
PCOMNAME pValidNames = NULL; // list of valid com names in registry
|
||
|
||
TOKMAP ptm[] = {
|
||
{L" ", TMFLAG_OPTIONAL, TMFORM_STRING, MAX_IDS_LEN, user_string},
|
||
{L"/d", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fDelete},
|
||
{L"/?", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &help_flag},
|
||
{L"/QUERY", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fquery},
|
||
{L"/Q", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fquery},
|
||
{0, 0, 0, 0, 0}
|
||
};
|
||
|
||
|
||
/*
|
||
* Constants
|
||
*/
|
||
#define DOSDEVICE_STRING L"\\DosDevices"
|
||
|
||
/*
|
||
* Local function prototypes.
|
||
*/
|
||
void Usage(BOOLEAN bError);
|
||
BOOL DeleteMappedPort(PWCHAR user_string);
|
||
BOOL GetPorts(PWCHAR user_string,
|
||
PWCHAR pwcSrcPort,
|
||
PWCHAR pwcDestPort,
|
||
ULONG ulbufsize);
|
||
BOOL MapPorts(PWCHAR pwcSrcPort,
|
||
PWCHAR pwcDestPort);
|
||
void ListSerialPorts();
|
||
BOOL IsSerialDevice(PWCHAR pwcName);
|
||
ULONG GetNTObjectName(PWCHAR pwcDOSdev,
|
||
PWCHAR pwcNTObjName,
|
||
ULONG ulbufsize);
|
||
ULONG AddComName(PCOMNAME *pComList,
|
||
PWCHAR pwcNTName,
|
||
PWCHAR pwcDOSName);
|
||
void DelComName(PCOMNAME pEntry);
|
||
PCOMNAME FindComName(PCOMNAME pComList,
|
||
PWCHAR pwcName);
|
||
|
||
BOOL IsVDMdeviceName(PWCHAR pwcName);
|
||
|
||
/*******************************************************************************
|
||
*
|
||
* main
|
||
*
|
||
******************************************************************************/
|
||
|
||
int __cdecl
|
||
main(INT argc, CHAR **argv)
|
||
{
|
||
WCHAR **argvW;
|
||
WCHAR wcSrcPort[MAX_PATH], wcDestPort[MAX_PATH];
|
||
ULONG ulSrcPort, ulDestPort, rc;
|
||
INT i;
|
||
|
||
setlocale(LC_ALL, ".OCP");
|
||
|
||
/*
|
||
* Massage the command line.
|
||
*/
|
||
|
||
argvW = MassageCommandLine((DWORD)argc);
|
||
if (argvW == NULL) {
|
||
ErrorPrintf(IDS_ERROR_MALLOC);
|
||
return(FAILURE);
|
||
}
|
||
|
||
/*
|
||
* parse the cmd line without parsing the program name (argc-1, argv+1)
|
||
*/
|
||
rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
|
||
|
||
/*
|
||
* Check for error from ParseCommandLine
|
||
*/
|
||
if ( help_flag || (rc && !(rc & PARSE_FLAG_NO_PARMS)) ) {
|
||
|
||
if ( !help_flag ) {
|
||
|
||
Usage(TRUE);
|
||
return(FAILURE);
|
||
|
||
} else {
|
||
|
||
Usage(FALSE);
|
||
return(SUCCESS);
|
||
}
|
||
}
|
||
|
||
//If we are not Running under Terminal Server, Return Error
|
||
|
||
if(!AreWeRunningTerminalServices())
|
||
{
|
||
ErrorPrintf(IDS_ERROR_NOT_TS);
|
||
return (FAILURE);
|
||
}
|
||
|
||
if (fDelete) {
|
||
DeleteMappedPort(user_string);
|
||
} else if (*user_string) {
|
||
GetPorts(user_string, wcSrcPort, wcDestPort, MAX_PATH);
|
||
MapPorts(wcSrcPort, wcDestPort);
|
||
} else { // query the mapped ports
|
||
ListSerialPorts();
|
||
}
|
||
|
||
// Free up the list of valid port names
|
||
if (pValidNames) {
|
||
PCOMNAME pEntry, pPrev;
|
||
|
||
pEntry = pValidNames;
|
||
while (pEntry) {
|
||
pPrev = pEntry;
|
||
pEntry = pEntry->com_pnext;
|
||
DelComName(pPrev);
|
||
}
|
||
}
|
||
|
||
return(SUCCESS);
|
||
}
|
||
|
||
|
||
/*******************************************************************************
|
||
*
|
||
* Usage
|
||
*
|
||
* Output the usage message for this utility.
|
||
*
|
||
* ENTRY:
|
||
* bError (input)
|
||
* TRUE if the 'invalid parameter(s)' message should preceed the usage
|
||
* message and the output go to stderr; FALSE for no such error
|
||
* string and output goes to stdout.
|
||
*
|
||
* EXIT:
|
||
*
|
||
*
|
||
******************************************************************************/
|
||
|
||
void
|
||
Usage( BOOLEAN bError )
|
||
{
|
||
if ( bError ) {
|
||
ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS);
|
||
}
|
||
ErrorPrintf(IDS_HELP_USAGE1);
|
||
ErrorPrintf(IDS_HELP_USAGE2);
|
||
ErrorPrintf(IDS_HELP_USAGE3);
|
||
ErrorPrintf(IDS_HELP_USAGE4);
|
||
ErrorPrintf(IDS_HELP_USAGE5);
|
||
|
||
} /* Usage() */
|
||
|
||
|
||
/*******************************************************************************
|
||
*
|
||
* DeleteMappedPort
|
||
*
|
||
* This routine deletes the specified mapped port
|
||
*
|
||
*
|
||
* ENTRY:
|
||
* PWCHAR pwcport (In): Pointer to port mapping to delete
|
||
*
|
||
* EXIT:
|
||
* TRUE: port was deleted
|
||
* FALSE: error deleting port
|
||
*
|
||
******************************************************************************/
|
||
|
||
BOOL DeleteMappedPort(PWCHAR pwcport)
|
||
{
|
||
ULONG rc;
|
||
PWCHAR pwch;
|
||
WCHAR wcbuff[MAX_PATH];
|
||
|
||
// Check if this a serial device and if it is, remove it
|
||
if (!GetNTObjectName(pwcport, wcbuff, sizeof(wcbuff)/sizeof(WCHAR)) &&
|
||
IsSerialDevice(wcbuff)) {
|
||
|
||
if (DefineDosDevice(DDD_REMOVE_DEFINITION,
|
||
pwcport,
|
||
NULL)) {
|
||
return(TRUE);
|
||
} else {
|
||
rc = GetLastError();
|
||
}
|
||
} else {
|
||
rc = ERROR_FILE_NOT_FOUND;
|
||
}
|
||
|
||
StringDwordErrorPrintf(IDS_ERROR_DEL_PORT_MAPPING, pwcport, rc);
|
||
|
||
return(FALSE);
|
||
}
|
||
|
||
|
||
/*******************************************************************************
|
||
*
|
||
* GetPorts
|
||
*
|
||
* This routine converts the string to the source and destination ports
|
||
*
|
||
*
|
||
* ENTRY:
|
||
* PWCHAR pwcstring (In): Pointer to user string
|
||
* PWCHAR pwcSrcPort (Out): Pointer to return source port
|
||
* PWCHAR pwcSrcPort (Out): Pointer to return destination port
|
||
* ULONG ulbufsize (In): Size of return buffers
|
||
*
|
||
* EXIT:
|
||
* TRUE: string converted to source and destination ports
|
||
* FALSE: error
|
||
*
|
||
******************************************************************************/
|
||
|
||
BOOL GetPorts(PWCHAR pwcstring, PWCHAR pwcSrcPort, PWCHAR pwcDestPort,
|
||
ULONG ulbufsize)
|
||
{
|
||
PWCHAR pwch;
|
||
ULONG ulcnt;
|
||
BOOL fSawEqual = FALSE;
|
||
|
||
pwch = pwcstring;
|
||
|
||
// find next non alphanumeric character
|
||
for (ulcnt = 0; pwch[ulcnt] && iswalnum(pwch[ulcnt]); ulcnt++) {
|
||
}
|
||
|
||
// Get the source port
|
||
if (pwch[ulcnt] && (ulcnt < ulbufsize)) {
|
||
wcsncpy(pwcSrcPort, pwch, ulcnt);
|
||
} else {
|
||
return(FALSE);
|
||
}
|
||
pwcSrcPort[ulcnt] = L'\0';
|
||
|
||
pwch += ulcnt;
|
||
|
||
// get to destination port
|
||
while (*pwch && !iswalnum(*pwch)) {
|
||
if (*pwch == L'=') {
|
||
fSawEqual = TRUE;
|
||
}
|
||
pwch++;
|
||
}
|
||
|
||
// If the syntax is OK and there's room in the buffer, copy the dest. port
|
||
if (*pwch && fSawEqual && (wcslen(pwch) < ulbufsize)) {
|
||
wcscpy(pwcDestPort, pwch);
|
||
} else {
|
||
return(FALSE);
|
||
}
|
||
|
||
// remove the : if they entered comn:
|
||
if (pwch = wcsrchr(pwcSrcPort, L':')) {
|
||
*pwch = L'\0';
|
||
}
|
||
if (pwch = wcsrchr(pwcDestPort, L':')) {
|
||
*pwch = L'\0';
|
||
}
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
/*******************************************************************************
|
||
*
|
||
* MapPorts
|
||
*
|
||
* This routine maps the source port number to the destination port.
|
||
*
|
||
*
|
||
* ENTRY:
|
||
* PWCHAR pwcSrcPort (In): Source port
|
||
* PWCHAR pwcDestPort (In): Destination port
|
||
*
|
||
* EXIT:
|
||
* TRUE: port was mapped
|
||
* FALSE: error mapping port
|
||
*
|
||
******************************************************************************/
|
||
|
||
BOOL MapPorts(PWCHAR pwcSrcPort, PWCHAR pwcDestPort)
|
||
{
|
||
ULONG rc = ERROR_FILE_NOT_FOUND;
|
||
WCHAR wcdest[MAX_PATH], wcsrc[MAX_PATH];
|
||
PWCHAR pFixedPort = NULL;
|
||
|
||
// Get the NT name of the destination and make sure it's a serial device
|
||
if (!GetNTObjectName(pwcDestPort, wcdest, sizeof(wcdest)/sizeof(WCHAR)) &&
|
||
IsSerialDevice(wcdest)) {
|
||
|
||
// see if this mapping already exists
|
||
if (!GetNTObjectName(pwcSrcPort, wcsrc, sizeof(wcsrc)/sizeof(WCHAR)) &&
|
||
!_wcsicmp(wcdest, wcsrc)) {
|
||
ErrorPrintf(IDS_ERROR_PORT_MAPPING_EXISTS,
|
||
pwcSrcPort,
|
||
pwcDestPort);
|
||
return(FALSE);
|
||
}
|
||
|
||
if (DefineDosDevice(DDD_RAW_TARGET_PATH,
|
||
pwcSrcPort,
|
||
wcdest)) {
|
||
return(TRUE);
|
||
} else {
|
||
rc = GetLastError();
|
||
}
|
||
}
|
||
|
||
StringDwordErrorPrintf(IDS_ERROR_CREATE_PORT_MAPPING, pwcSrcPort, rc);
|
||
|
||
return(FALSE);
|
||
}
|
||
|
||
|
||
/*******************************************************************************
|
||
*
|
||
* GetNTObjectName
|
||
*
|
||
* This routine returns the NT object name for a DOS device.
|
||
*
|
||
* ENTRY:
|
||
* PWCHAR pwcDOSdev (In): pointer to DOS device name
|
||
* PWCHAR pwcNTObjName (Out): pointer for NT object name
|
||
* ULONG ulbufsize (In): size (in wide chars) of object name buffer
|
||
*
|
||
* EXIT:
|
||
* Success:
|
||
* returns 0
|
||
* Failure:
|
||
* returns error code
|
||
*
|
||
******************************************************************************/
|
||
|
||
ULONG GetNTObjectName(PWCHAR pwcDOSdev, PWCHAR pwcNTObjName, ULONG ulbufsize)
|
||
{
|
||
WCHAR wcbuff[MAX_PATH];
|
||
PWCHAR pwch;
|
||
|
||
// Make a copy of the name passed in
|
||
wcscpy(wcbuff, pwcDOSdev);
|
||
|
||
// Strip off any trailing colon (comn:)
|
||
if (pwch = wcsrchr(wcbuff, L':')) {
|
||
*pwch = L'\0';
|
||
}
|
||
|
||
if (QueryDosDevice(pwcDOSdev, pwcNTObjName, ulbufsize)) {
|
||
return(0);
|
||
} else {
|
||
return(GetLastError());
|
||
}
|
||
}
|
||
|
||
|
||
/*******************************************************************************
|
||
*
|
||
* ListSerialPorts
|
||
*
|
||
* This routine lists all of the mapped ports.
|
||
*
|
||
* ENTRY:
|
||
*
|
||
* EXIT:
|
||
*
|
||
******************************************************************************/
|
||
|
||
void ListSerialPorts(void)
|
||
{
|
||
ULONG ulcnt, rc;
|
||
// WCHAR DeviceNames[4096];
|
||
WCHAR TargetPath[4096];
|
||
PWCH pwch;
|
||
PCOMNAME pComList = NULL;
|
||
PCOMNAME pEntry, pPrev;
|
||
|
||
DWORD dwBufferSize = 2048;
|
||
WCHAR *DeviceNames = malloc(dwBufferSize);
|
||
|
||
if (!DeviceNames) {
|
||
|
||
ErrorPrintf(IDS_ERROR_MALLOC);
|
||
return;
|
||
}
|
||
|
||
|
||
//
|
||
// Get all of the defined DOS devices
|
||
//
|
||
|
||
//
|
||
// QueryDosDevice function returns success even if buffer is too small!
|
||
// Lets get around it
|
||
//
|
||
|
||
SetLastError(0);
|
||
while (!QueryDosDevice( NULL,
|
||
DeviceNames,
|
||
dwBufferSize/sizeof(WCHAR)) ||
|
||
GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
|
||
|
||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||
{
|
||
SetLastError(0);
|
||
free(DeviceNames);
|
||
dwBufferSize *= 2;
|
||
|
||
DeviceNames = malloc(dwBufferSize);
|
||
|
||
if (!DeviceNames)
|
||
{
|
||
ErrorPrintf(IDS_ERROR_MALLOC);
|
||
return;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
ErrorPrintf(IDS_ERROR_GETTING_COMPORTS, GetLastError());
|
||
}
|
||
}
|
||
|
||
pwch = DeviceNames;
|
||
|
||
// Go through each DOS device and get it's NT object name, then check if
|
||
// it's a serial device, and if so display it
|
||
while (*pwch) {
|
||
rc = GetNTObjectName(pwch,
|
||
TargetPath,
|
||
sizeof(TargetPath)/sizeof(WCHAR));
|
||
if (rc) {
|
||
ErrorPrintf(IDS_ERROR_GETTING_COMPORTS, rc);
|
||
} else if (IsSerialDevice(TargetPath)) {
|
||
AddComName(&pComList, TargetPath, pwch);
|
||
}
|
||
|
||
pwch += wcslen(pwch) + 1;
|
||
}
|
||
|
||
if (pComList) {
|
||
// print out the entries
|
||
pEntry = pComList;
|
||
while (pEntry) {
|
||
wprintf(L"%s = %s\n", pEntry->com_pwcDOSName, pEntry->com_pwcNTName);
|
||
pPrev = pEntry;
|
||
pEntry = pEntry->com_pnext;
|
||
DelComName(pPrev);
|
||
}
|
||
} else {
|
||
ErrorPrintf(IDS_ERROR_NO_SERIAL_PORTS);
|
||
}
|
||
|
||
free(DeviceNames);
|
||
|
||
}
|
||
|
||
|
||
/*******************************************************************************
|
||
*
|
||
* IsSerialDevice
|
||
*
|
||
* This routine checks if the NT file name is a serial device
|
||
*
|
||
*
|
||
* ENTRY:
|
||
* PWCHAR pwcName (In): Pointer to name to check
|
||
*
|
||
* EXIT:
|
||
* TRUE: Is a serial device
|
||
* FALSE: Not a serial device
|
||
*
|
||
******************************************************************************/
|
||
|
||
BOOL IsSerialDevice(PWCHAR pwcName)
|
||
{
|
||
NTSTATUS Status;
|
||
HANDLE Handle;
|
||
IO_STATUS_BLOCK IoStatusBlock;
|
||
FILE_FS_DEVICE_INFORMATION FileFSDevInfo;
|
||
OBJECT_ATTRIBUTES ObjFile;
|
||
UNICODE_STRING UniFile;
|
||
WCHAR wcbuff[MAX_PATH];
|
||
WCHAR wcvalue[MAX_PATH];
|
||
PWCHAR pwch;
|
||
HKEY hKey;
|
||
ULONG ulType, ulSize, ulcnt, ulValSize;
|
||
BOOL fIsSerial = FALSE;
|
||
|
||
|
||
if (IsVDMdeviceName(pwcName)) {
|
||
return FALSE;
|
||
}
|
||
|
||
RtlInitUnicodeString(&UniFile, pwcName);
|
||
|
||
InitializeObjectAttributes(&ObjFile,
|
||
&UniFile,
|
||
OBJ_CASE_INSENSITIVE,
|
||
NULL,
|
||
NULL);
|
||
|
||
//
|
||
// Open the device
|
||
//
|
||
Status = NtOpenFile(&Handle,
|
||
(ACCESS_MASK)FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
||
&ObjFile,
|
||
&IoStatusBlock,
|
||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
|
||
|
||
if (NT_SUCCESS(Status)) {
|
||
Status = NtQueryVolumeInformationFile(Handle,
|
||
&IoStatusBlock,
|
||
&FileFSDevInfo,
|
||
sizeof(FileFSDevInfo),
|
||
FileFsDeviceInformation);
|
||
|
||
// Check if this is actually a serial device or not
|
||
if (NT_SUCCESS(Status) &&
|
||
(FileFSDevInfo.DeviceType == FILE_DEVICE_SERIAL_PORT)) {
|
||
fIsSerial = TRUE;
|
||
}
|
||
|
||
// Close the file handle
|
||
NtClose(Handle);
|
||
|
||
} else {
|
||
// If we couldn't open the device, look for the name in the registry
|
||
|
||
#ifdef DEBUG
|
||
wprintf(L"Error opening: %s, error = %x\n", pwcName, Status);
|
||
#endif
|
||
|
||
// strip off the leading \device
|
||
pwch = wcschr(pwcName+2, L'\\');
|
||
if (pwch != NULL)
|
||
{
|
||
pwch++;
|
||
|
||
|
||
// If we haven't built the list of valid names from the registry,
|
||
// build it.
|
||
if (pValidNames == NULL) {
|
||
// Open the serialcomm entry in the registry
|
||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||
L"Hardware\\DeviceMap\\SerialComm",
|
||
0,
|
||
KEY_READ,
|
||
&hKey) == ERROR_SUCCESS) {
|
||
|
||
ulValSize = ulSize = MAX_PATH;
|
||
ulcnt = 0;
|
||
|
||
// Put all of the valid entries into the valid names list
|
||
while (!RegEnumValue (hKey, ulcnt++, wcvalue, &ulValSize,
|
||
NULL, &ulType, (LPBYTE) wcbuff, &ulSize))
|
||
{
|
||
if (ulType != REG_SZ)
|
||
continue;
|
||
|
||
AddComName(&pValidNames, wcvalue, wcbuff);
|
||
|
||
ulValSize = ulSize = MAX_PATH;
|
||
}
|
||
|
||
RegCloseKey(hKey);
|
||
}
|
||
}
|
||
|
||
// look for the name in the list of valid com names
|
||
if (FindComName(pValidNames, pwch)) {
|
||
fIsSerial = TRUE;
|
||
}
|
||
}
|
||
}
|
||
|
||
return(fIsSerial);
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* AddComName
|
||
*
|
||
* This routines adds a new node onto the specified com port names.
|
||
*
|
||
* ENTRY:
|
||
* PCOMNAME *pComList (In) - Pointer to list to add entry to
|
||
* PWCHAR pwcNTName (In) - NT name of device
|
||
* PWCHAR pwcDOSName (In) - DOW name of device
|
||
*
|
||
* EXIT:
|
||
* SUCCESS:
|
||
* return ERROR_SUCCESS
|
||
* FAILURE:
|
||
* returns error code
|
||
*
|
||
****************************************************************************/
|
||
|
||
ULONG AddComName(PCOMNAME *pComList,
|
||
PWCHAR pwcNTName,
|
||
PWCHAR pwcDOSName)
|
||
{
|
||
PCOMNAME pnext, pprev, pnew;
|
||
LONG rc = ERROR_SUCCESS;
|
||
|
||
if (pnew = malloc(sizeof(COMNAME))) {
|
||
|
||
// clear out the new entry
|
||
memset(pnew, 0, sizeof(COMNAME));
|
||
|
||
// Allocate and initialize the NT name
|
||
if (pnew->com_pwcNTName =
|
||
malloc((wcslen(pwcNTName) + 1)*sizeof(WCHAR))) {
|
||
wcscpy(pnew->com_pwcNTName, pwcNTName);
|
||
} else {
|
||
rc = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
|
||
// Allocate and initialize the DOS name
|
||
if ((rc == ERROR_SUCCESS) && (pnew->com_pwcDOSName =
|
||
malloc((wcslen(pwcDOSName) + 1)*sizeof(WCHAR)))) {
|
||
wcscpy(pnew->com_pwcDOSName, pwcDOSName);
|
||
} else {
|
||
rc = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
} else {
|
||
rc = ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
|
||
// If we allocate everything OK, add the node into the list
|
||
if (rc == ERROR_SUCCESS) {
|
||
pprev = NULL;
|
||
pnext = *pComList;
|
||
|
||
// Insert the entry into the list in ascending order
|
||
while (pnext &&
|
||
((rc = _wcsicmp(pwcDOSName, pnext->com_pwcDOSName)) > 0)) {
|
||
pprev = pnext;
|
||
pnext = pnext->com_pnext;
|
||
}
|
||
|
||
// just return if this name is already in the list
|
||
if (pnext && (rc == 0)) {
|
||
return(ERROR_SUCCESS);
|
||
}
|
||
|
||
// Insert this entry into the list
|
||
pnew->com_pnext = pnext;
|
||
|
||
// If this is going to the front of the list, update list pointer
|
||
if (pprev == NULL) {
|
||
*pComList = pnew;
|
||
} else {
|
||
pprev->com_pnext = pnew;
|
||
}
|
||
|
||
} else if (pnew) {
|
||
|
||
// Didn't allocate everything, release the memory we got
|
||
DelComName(pnew);
|
||
}
|
||
|
||
return(rc);
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* DelComName
|
||
*
|
||
* This routines frees up the memory allocated to a com name node.
|
||
*
|
||
* ENTRY:
|
||
* PCOMNAME pEntry (In) - Node to delete
|
||
*
|
||
* EXIT:
|
||
* NONE
|
||
*
|
||
****************************************************************************/
|
||
|
||
void DelComName(PCOMNAME pEntry)
|
||
{
|
||
if (pEntry) {
|
||
if (pEntry->com_pwcNTName) {
|
||
free(pEntry->com_pwcNTName);
|
||
}
|
||
if (pEntry->com_pwcDOSName) {
|
||
free(pEntry->com_pwcDOSName);
|
||
}
|
||
free(pEntry);
|
||
}
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* FindComName
|
||
*
|
||
* This routines searches for the specified name in the com port list.
|
||
*
|
||
* ENTRY:
|
||
* PCOMNAME pComList (In) - List to search
|
||
* PWCHAR pwcName (In) - Name to search for
|
||
*
|
||
* EXIT:
|
||
* SUCCESS:
|
||
* returns pointer to node containing the specified name
|
||
* FAILURE:
|
||
* returns NULL (name not found)
|
||
*
|
||
****************************************************************************/
|
||
|
||
PCOMNAME FindComName(PCOMNAME pComList,
|
||
PWCHAR pwcName)
|
||
{
|
||
PCOMNAME pcom;
|
||
|
||
pcom = pComList;
|
||
while (pcom) {
|
||
//Check if the name matches either the NT or DOS device name
|
||
if (!_wcsicmp(pwcName, pcom->com_pwcDOSName) ||
|
||
!_wcsicmp(pwcName, pcom->com_pwcNTName)) {
|
||
return(pcom);
|
||
}
|
||
pcom = pcom->com_pnext;
|
||
}
|
||
return(NULL);
|
||
}
|
||
|
||
BOOL IsVDMdeviceName(PWCHAR pwcName)
|
||
{
|
||
UINT index;
|
||
UINT vdmlength = wcslen(L"VDM");
|
||
|
||
for (index = 0; (index+vdmlength-1) < wcslen(pwcName); index++) {
|
||
if (_wcsnicmp(&pwcName[index], L"VDM", vdmlength) == 0) {
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
return FALSE;
|
||
|
||
}
|
||
|
||
|
||
|