Ejemplo n.º 1
0
BOOL CEnumerateSerial::UsingEnumPorts(CSimpleArray<UINT>& ports)
#endif
{
  //Make sure we clear out any elements which may already be in the array
#if defined CENUMERATESERIAL_USE_STL
  ports.clear();
#else
  ports.RemoveAll();
#endif  

  //Call the first time to determine the size of the buffer to allocate
  DWORD cbNeeded = 0;
  DWORD dwPorts = 0;
  EnumPorts(NULL, 1, NULL, 0, &cbNeeded, &dwPorts);

  //What will be the return value
  BOOL bSuccess = FALSE;

  //Allocate the buffer and recall
  CAutoHeapAlloc portsBuffer;
  if (portsBuffer.Allocate(cbNeeded))
  {
    BYTE* pPorts = static_cast<BYTE*>(portsBuffer.m_pData);
    bSuccess = EnumPorts(NULL, 1, pPorts, cbNeeded, &cbNeeded, &dwPorts);
    if (bSuccess)
    {
      PORT_INFO_1* pPortInfo = reinterpret_cast<PORT_INFO_1*>(pPorts);
      for (DWORD i=0; i<dwPorts; i++)
      {
        //If it looks like "COMX" then
        //add it to the array which will be returned
        size_t nLen = _tcslen(pPortInfo->pName);
        if (nLen > 3)
        {
          if ((_tcsnicmp(pPortInfo->pName, _T("COM"), 3) == 0) && IsNumeric(&(pPortInfo->pName[3]), TRUE))
          {
            //Work out the port number
            int nPort = _ttoi(&(pPortInfo->pName[3]));
          #if defined CENUMERATESERIAL_USE_STL
            ports.push_back(nPort);
          #else
            ports.Add(nPort);
          #endif  
          }
        }

        pPortInfo++;
      }
    }
  }
  else
    SetLastError(ERROR_OUTOFMEMORY);        
  
  return bSuccess;
}
Ejemplo n.º 2
0
static BOOL test_EnumPorts(struct torture_context *tctx,
			   LPSTR servername)
{
	DWORD levels[]  = { 1, 2 };
	DWORD success[] = { 1, 1 };
	DWORD i;
	LPBYTE buffer = NULL;

	for (i=0; i < ARRAY_SIZE(levels); i++) {

		DWORD needed = 0;
		DWORD returned = 0;
		DWORD err = 0;
		char tmp[1024];

		torture_comment(tctx, "Testing EnumPorts level %d", levels[i]);

		EnumPorts(servername, levels[i], NULL, 0, &needed, &returned);
		err = GetLastError();
		if (err == ERROR_INSUFFICIENT_BUFFER) {
			err = 0;
			buffer = malloc(needed);
			torture_assert(tctx, buffer, "malloc failed");
			if (!EnumPorts(servername, levels[i], buffer, needed, &needed, &returned)) {
				err = GetLastError();
			}
		}
		if (err) {
			sprintf(tmp, "EnumPorts failed level %d on [%s] (buffer size = %d), error: %s\n",
				levels[i], servername, needed, errstr(err));
			if (success[i]) {
				torture_fail(tctx, tmp);
			} else {
				torture_warning(tctx, tmp);
			}
		}

		free(buffer);
		buffer = NULL;
	}

	return TRUE;
}
Ejemplo n.º 3
0
int PASCAL 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
{
DWORD version = GetVersion();
   phInstance = hInstance;
   if ((HIWORD(version) & 0x8000)==0)
      is_winnt = TRUE;
   if (LOBYTE(LOWORD(version)) >= 4)
      is_win4 = TRUE;

   if (lstrlen(lpszCmdLine))
       silent = TRUE;

   LoadString(phInstance, IDS_TITLE, title, sizeof(title)/sizeof(TCHAR)-1);
   LoadString(phInstance, IDS_MONITORNAME, monitorname, 
	sizeof(monitorname)/sizeof(TCHAR)-1);

   /* Check that it really is installed */
   if (EnumMonitors(NULL, 1, (LPBYTE)buffer, sizeof(buffer), 
        &needed, &returned)) {
      MONITOR_INFO_1 *mi;
      mi = (MONITOR_INFO_1 *)buffer;
      for (i=0; i<returned; i++) {
	 if (lstrcmp(mi[i].pName, monitorname) == 0)
	    break;
      }
   }
   else
      return message(IDS_ENUMMONITORS_FAILED);

   if (i == returned)
	return message(IDS_NOT_INSTALLED);

   /* Warn user about what we are about to do */
   if (!silent) {
         TCHAR buf[256];
	 LoadString(phInstance, IDS_INTRO, buf, sizeof(buf)/sizeof(TCHAR)-1);
         if (MessageBox(HWND_DESKTOP, buf, title, MB_YESNO) != IDYES)
	     return 0;
   }

   /* Check if monitor is still in use */
   rc = EnumPorts(NULL, 2, (LPBYTE)buffer, sizeof(buffer), 
      &needed, &returned);
   pi2 = (PORT_INFO_2 *)buffer;
   if (rc) {
      for (i=0; i<returned; i++) {
	 if (lstrcmp(pi2[i].pMonitorName, monitorname) == 0) {
            TCHAR buf[256];
	    LoadString(phInstance, IDS_INUSE, buf, sizeof(buf)/sizeof(TCHAR)-1);
	    wsprintf(sysdir, buf, pi2[i].pPortName);
            MessageBox(HWND_DESKTOP, sysdir, title, MB_OK);
	    return 1;
	 }
      }
   }
   else
      return message(IDS_ENUMPORTS_FAILED);

   /* Try to delete the monitor */
   if (!DeleteMonitor(NULL,  
      NULL /* is_winnt ? MONITORENVNT : MONITORENV95 */, 
      monitorname))
	return message(IDS_DELETEMONITOR_FAILED);

   /* Delete the monitor files */
   if (!GetSystemDirectory(sysdir, sizeof(sysdir)))
	return message(IDS_NOSYSDIR);
   lstrcpy(buffer, sysdir);
   lstrcat(buffer, "\\");
   lstrcat(buffer, is_winnt ? MONITORDLLNT : MONITORDLL95);
   if (!DeleteFile(buffer))
	return message(IDS_ERROR_DELETE_DLL);
   lstrcpy(buffer, sysdir);
   lstrcat(buffer, "\\");
   lstrcat(buffer, MONITORHLP);
   if (!DeleteFile(buffer))
	return message(IDS_ERROR_DELETE_HELP);
   lstrcpy(buffer, sysdir);
   lstrcat(buffer, "\\");
   lstrcat(buffer, REDCONF);
   if (!DeleteFile(buffer))
       return message(IDS_ERROR_DELETE_REDCONF);

   /* delete registry entries for uninstall */
   if ((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, UNINSTALLKEY, 0, 
	KEY_ALL_ACCESS, &hkey)) == ERROR_SUCCESS) {
	RegDeleteKey(hkey, MONITORKEY);
	RegCloseKey(hkey);
   }

   /* Delete this program, but we can't do it while we are running.
    * Defer deletion until next reboot
    */
   wsprintf(buffer, TEXT("%s\\%s"), sysdir, UNINSTALLPROG);
   if (is_winnt) {
        MoveFileEx(buffer, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
   }
   else {
	char ininame[256];
	GetWindowsDirectory(ininame, sizeof(ininame));
	lstrcat(ininame, "\\wininit.ini");
	/* This method is dodgy, because multiple applications
         * using this method to delete files will overwrite
         * earlier delete instructions.
         */
	WritePrivateProfileString("Rename", "NUL", buffer, ininame);
	SetLastError(0);
   }

#ifdef UNUSED
   /* We should delete this program, but we can't do it
    * while we are running.
    * I think there is a registry key we can create which says
    * "Delete these files on next reboot", but I can't find the 
    * documentation about it.
    * Instead, run a DOS window once to delete the file
    */
    if ((rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
	"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
	0, KEY_ALL_ACCESS, &hkey)) == ERROR_SUCCESS) {
	wsprintf(buffer, "command /c del %s\\%s", sysdir, UNINSTALLPROG);
	RegSetValueEx(hkey, MONITORKEY, 0, REG_SZ,
	    (CONST BYTE *)buffer, lstrlen(buffer)+1);
    }
#endif
   
   
   message(IDS_UNINSTALLED);

   return 0;
}
Ejemplo n.º 4
0
extern "C" __declspec (dllexport) void SerialGate::GetPortsInfo(PortInfo* pi)
{

  DWORD  Ports_MemSize = 0;
  DWORD  Ports_Count   = 0;
  BYTE*  lpPorts       = NULL;

  //Getting Ports_MemSize value...
  EnumPorts(NULL,
            1,
            lpPorts,
            0,
            &Ports_MemSize,
            &Ports_Count);


  //Getting lpPorts...
  lpPorts = new BYTE[Ports_MemSize];
  EnumPorts(NULL,
            1,
            lpPorts,
            Ports_MemSize,
            &Ports_MemSize,
            &Ports_Count);


  //Forming List Of Ports...
  DWORD dw;
  TCHAR str[8];
  char temp[4];
  int port = -1;
  PORT_INFO_1 *pPortInfo;
  pPortInfo = (PORT_INFO_1 *)lpPorts;


  int counter = 0;
  bool av = false;

  for (dw = 0; dw < Ports_Count; dw++)
  {
    
    lstrcpyn(str, pPortInfo->pName, 4);
    str[4] = 0;
    if (lstrcmpi(str, "com") == 0)
    {    
		//printf("%s\n", pPortInfo->pName);	

		memset(temp, '\0', sizeof(temp));

		temp[0] = pPortInfo->pName[3];
		if(pPortInfo->pName[4]!= ':' && pPortInfo->pName[4]!= '\0')
			temp[1] = pPortInfo->pName[4];
		if(pPortInfo->pName[5]!= ':' && pPortInfo->pName[5]!= '\0')
			temp[2] = pPortInfo->pName[5];		

		port = atoi(temp);

		//printf("%d\n", port);

		
		char COM_string[20];
		sprintf(COM_string,"\\\\.\\COM%d", port);

		HANDLE h = CreateFile(COM_string, GENERIC_READ|GENERIC_WRITE, 0, NULL,						
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);

		if(h == INVALID_HANDLE_VALUE)
		{				
			//return false;
			av = false;
		}
		else
		{
			av = true;
			CloseHandle(h);
		}



		pi->p[counter].Id      = port;
		pi->p[counter].Availbl = av;
		counter++;
		
		
    }

    pPortInfo++;
  }
  
  pi->koll = counter;

  delete [] lpPorts;
	
}
Ejemplo n.º 5
0
//////////////////////////////////////////////////////////////////////
//
// Function:    InitMusic
// Date:		20/10/99
// Author:		Macca
//
//Description:	set up Direct Music object, performance, loader and
//				enumerate music devices
//
//////////////////////////////////////////////////////////////////////
bool Music::Init(DigitalDriver* drvr)
{
	if (this && drvr)
	{
		HRESULT res;

//ensure that a DirectSound object exists, if not then no music

		if (!drvr->lpds)
			return false;

// If an instance already exists, kill it and reset...

		if (MusicAllowed)
			CleanUpMusic();

// set global directmusic performance pointer

		res=CoCreateInstance(
			CLSID_DirectMusicPerformance,
			NULL,
			CLSCTX_INPROC,
			IID_IDirectMusicPerformance,
			(void**)&gpPerf
			);

		if (res!=S_OK)
		{
			gpPerf=NULL;
			return false;
		}

// let performance create DirectMusic object
// link to existing DirectSound object

		res=gpPerf->Init(&gpDMusic,drvr->lpds,NULL);

		if (res!=S_OK)
		{
// dont CloseDown if Init failed

//			gpPerf->CloseDown();

			gpPerf->Release();
			gpPerf=NULL;
			return false;
		}

// create loader responsible for loading, finding, enumerating and caching DirectMusic objects

		if (!CreateLoader())
			return false;

// get list of devices that we will show to the player

		EnumPorts();

// everything seems OK, allow music

		MusicAllowed=true;
		dig = drvr;												//RJS 09Nov99

		SetVolume(127);										//RJS 09Nov99

		return true;
	}

	return false;
}
Ejemplo n.º 6
0
BOOL
EnumGeneric(
    IN  PROC    fnEnum,
    IN  DWORD   Level,
    IN  PBYTE   *ppEnumData,
    IN  DWORD   cbBuf,
    OUT LPDWORD pcbReturned,
    OUT LPDWORD pcReturned,
    IN  PVOID   Arg1,
    IN  PVOID   Arg2,
    IN  PVOID   Arg3 )
{
    BOOL   rc;
    BOOL   UnknownFunction = FALSE;
    DWORD  cbRealloc;

    if( fnEnum == (PROC)EnumPrinters )
        rc = EnumPrinters( (DWORD)Arg1, (LPTSTR)Arg2, COMMON_ARGS );
                           // Flags        Name
    else if( fnEnum == (PROC)EnumJobs )
        rc = EnumJobs( (HANDLE)Arg1, (DWORD)Arg2, (DWORD)Arg3, COMMON_ARGS );
                       // hPrinter      FirstJob     NoJobs
    else if( fnEnum == (PROC)EnumPrinterDrivers )
        rc = EnumPrinterDrivers( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS );
                                 // pName        pEnvironment
    else if( fnEnum == (PROC)EnumForms )
        rc = EnumForms( (HANDLE)Arg1, COMMON_ARGS );
                        // hPrinter
    else if( fnEnum == (PROC)EnumMonitors )
        rc = EnumMonitors( (LPTSTR)Arg1, COMMON_ARGS );
                           // pName
    else if( fnEnum == (PROC)EnumPorts )
        rc = EnumPorts( (LPTSTR)Arg1, COMMON_ARGS );
                        // pName
    else if( fnEnum == (PROC)EnumPrintProcessors )
        rc = EnumPrintProcessors( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS );
                                  // pName        pEnvironment
    else if( fnEnum == (PROC)EnumPrintProcessorDatatypes )
        rc = EnumPrintProcessorDatatypes( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS );
                                          // pName        pPrintProcessorName
    else
    {
        *ppEnumData = NULL;
        UnknownFunction = TRUE;

        DBGMSG( DBG_ERROR, ( "EnumGeneric called with unknown function\n" ) );

        rc = FALSE;
    }


    if( ( rc == FALSE ) && ( UnknownFunction == FALSE ) )
    {
        if( GetLastError( ) == ERROR_INSUFFICIENT_BUFFER )
        {
            cbRealloc = *pcbReturned;

            DBGMSG( DBG_TRACE, ( "EnumGeneric: Reallocating %d (0x%x) bytes @%08x\n",
                                 cbBuf, cbBuf, *ppEnumData ) );

            if( cbBuf == 0 )
                *ppEnumData = AllocSplMem( cbRealloc );
            else
                *ppEnumData = ReallocSplMem( *ppEnumData, cbRealloc );

            cbBuf = cbRealloc;

            if( *ppEnumData )
            {
                DBGMSG( DBG_TRACE, ( "EnumGeneric: %d (0x%x) bytes reallocated @%08x\n",
                                     cbBuf, cbBuf, *ppEnumData ) );

             if( fnEnum == (PROC)EnumPrinters )
                    rc = EnumPrinters( (DWORD)Arg1, (LPTSTR)Arg2, COMMON_ARGS );
                                       // Flags        Name
             else if( fnEnum == (PROC)EnumJobs )
                    rc = EnumJobs( (HANDLE)Arg1, (DWORD)Arg2, (DWORD)Arg3, COMMON_ARGS );
                                   // hPrinter      FirstJob     NoJobs
                else if( fnEnum == (PROC)EnumPrinterDrivers )
                    rc = EnumPrinterDrivers( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS );
                                             // pName        pEnvironment
                else if( fnEnum == (PROC)EnumForms )
                    rc = EnumForms( (HANDLE)Arg1, COMMON_ARGS );
                                    // hPrinter
                else if( fnEnum == (PROC)EnumMonitors )
                    rc = EnumMonitors( (LPTSTR)Arg1, COMMON_ARGS );
                                       // pName
                else if( fnEnum == (PROC)EnumPorts )
                    rc = EnumPorts( (LPTSTR)Arg1, COMMON_ARGS );
                                    // pName
                else if( fnEnum == (PROC)EnumPrintProcessors )
                    rc = EnumPrintProcessors( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS );
                                              // pName        pEnvironment
                else if( fnEnum == (PROC)EnumPrintProcessorDatatypes )
                    rc = EnumPrintProcessorDatatypes( (LPTSTR)Arg1, (LPTSTR)Arg2, COMMON_ARGS );
                                                      // pName        pPrintProcessorName

                /* If things haven't worked out, free up the buffer.
                 * We do this because otherwise the caller will not know
                 * whether the pointer is valid any more,
                 * since ReallocSplMem might have failed.
                 */
                if( rc == FALSE )
                {
                    if( *ppEnumData )
                        FreeSplMem( *ppEnumData );
                    *ppEnumData = NULL;
                    *pcbReturned = 0;
                    *pcReturned = 0;
                }

                /* Don't rely on pcbReturned having the same value
                 * that was passed in:
                 */
                else
                    *pcbReturned = cbRealloc;
            }
        }

        else
        {
            if( *ppEnumData )
                FreeSplMem( *ppEnumData );
            *ppEnumData = NULL;
            *pcbReturned = 0;
            *pcReturned = 0;
            rc = FALSE;
        }
    }

    else
        *pcbReturned = cbBuf;

    return rc;
}
Ejemplo n.º 7
0
//-------------------------------------------------------------------------------------
DWORD WINAPI MfmXcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData,
						    DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData,
						    PDWORD pcbOutputNeeded)
{
	g_pLog->Log(LOGLEVEL_ALL, L"MfmXcvDataPort called (%s)", pszDataName);

	LPXCVDATA pXCVDATA = (LPXCVDATA)hXcv;
	if (wcscmp(pszDataName, L"AddPort") == 0)
	{
/*
		if (pXCVDATA != NULL && pInputData != NULL)
		{
			if (!(pXCVDATA->GrantedAccess & SERVER_ACCESS_ADMINISTER))
				return ERROR_ACCESS_DENIED;
			pXCVDATA->pPort = new CPort((LPWSTR)pInputData);
			g_pPortList->AddMfmPort(pXCVDATA->pPort);
			return ERROR_SUCCESS;
		}
		return ERROR_BAD_ARGUMENTS;
*/
		return ERROR_CAN_NOT_COMPLETE;
	}
	else if (wcscmp(pszDataName, L"DeletePort") == 0)
	{
/*
		if (pXCVDATA != NULL && pXCVDATA->pPort != NULL)
		{
			if (!(pXCVDATA->GrantedAccess & SERVER_ACCESS_ADMINISTER))
				return ERROR_ACCESS_DENIED;
			pXCVDATA->bDeleting = TRUE;
			g_pPortList->DeletePort(pXCVDATA->pPort);
			return ERROR_SUCCESS;
		}
		return ERROR_BAD_ARGUMENTS;
*/
		return ERROR_CAN_NOT_COMPLETE;
	}
	else if (wcscmp(pszDataName, L"PortDeleted") == 0)
	{
/*
		if (pXCVDATA != NULL)
		{
			if (!(pXCVDATA->GrantedAccess & SERVER_ACCESS_ADMINISTER))
				return ERROR_ACCESS_DENIED;
			pXCVDATA->bDeleting = FALSE;
			return ERROR_SUCCESS;
		}
		return ERROR_BAD_ARGUMENTS;
*/
		return ERROR_CAN_NOT_COMPLETE;
	}
	else if (wcscmp(pszDataName, L"PortExists") == 0)
	{
		LPWSTR szPortName = (LPWSTR)pInputData;
		DWORD needed, returned;
		if (EnumPorts(NULL, 1, NULL, 0, &needed, &returned) == 0 &&
			GetLastError() == ERROR_INSUFFICIENT_BUFFER)
		{
			HANDLE hHeap = GetProcessHeap();
			LPBYTE pBuf;
			if ((pBuf = (LPBYTE)HeapAlloc(hHeap, 0, needed)) == NULL)
				return ERROR_OUTOFMEMORY;
			if (EnumPorts(NULL, 1, pBuf, needed, &needed, &returned))
			{
				PORT_INFO_1W* pPorts = (PORT_INFO_1W*)pBuf;
				while (returned--)
				{
					if (_wcsicmp(szPortName, pPorts->pName) == 0)
					{
						*((BOOL*)pOutputData) = TRUE;
						break;
					}
					pPorts++;
				}
			}
			HeapFree(hHeap, 0, pBuf);
			return ERROR_SUCCESS;
		}
	}
	else if (wcscmp(pszDataName, L"SetConfig") == 0)
	{
		if (cbInputData < sizeof(PORTCONFIG))
			return ERROR_INSUFFICIENT_BUFFER;
		if (pXCVDATA != NULL && pXCVDATA->pPort != NULL && pInputData != NULL)
		{
			if (!(pXCVDATA->GrantedAccess & SERVER_ACCESS_ADMINISTER))
				return ERROR_ACCESS_DENIED;
			LPPORTCONFIG ppc = (LPPORTCONFIG)pInputData;
			pXCVDATA->pPort->SetConfig(ppc->szPortName/*, ppc->szOutputPath, ppc->szFilePattern,
				ppc->bOverwrite, ppc->szUserCommandPattern, ppc->szExecPath, ppc->bWaitTermination,
				ppc->bPipeData, ppc->nLogLevel*/);
			g_pPortList->SaveToRegistry();
			return ERROR_SUCCESS;
		}
		return ERROR_BAD_ARGUMENTS;
	}
	else if (wcscmp(pszDataName, L"GetConfig") == 0)
	{
		*pcbOutputNeeded = sizeof(PORTCONFIG);
		if (*pcbOutputNeeded > cbOutputData)
			return ERROR_INSUFFICIENT_BUFFER;
		if (pXCVDATA != NULL && pXCVDATA->pPort != NULL && pOutputData != NULL)
		{
			LPPORTCONFIG ppc = (LPPORTCONFIG)pOutputData;
			wcscpy_s(ppc->szPortName, LENGTHOF(ppc->szPortName), pXCVDATA->pPort->PortName());
//			wcscpy_s(ppc->szOutputPath, LENGTHOF(ppc->szOutputPath), pXCVDATA->pPort->OutputPath());
//			wcscpy_s(ppc->szFilePattern, LENGTHOF(ppc->szFilePattern), pXCVDATA->pPort->FilePattern());
//			ppc->bOverwrite = pXCVDATA->pPort->Overwrite();
//			wcscpy_s(ppc->szUserCommandPattern, LENGTHOF(ppc->szUserCommandPattern), pXCVDATA->pPort->UserCommandPattern());
//			wcscpy_s(ppc->szExecPath, LENGTHOF(ppc->szExecPath), pXCVDATA->pPort->ExecPath());
//			ppc->bWaitTermination = pXCVDATA->pPort->WaitTermination();
//			ppc->bPipeData = pXCVDATA->pPort->PipeData();
//			ppc->nLogLevel = g_pLog->GetLogLevel();
			return ERROR_SUCCESS;
		}
		return ERROR_BAD_ARGUMENTS;
	}
	else if (wcscmp(pszDataName, L"MonitorUI") == 0)
	{
		static WCHAR szUIDLL[] = L"wphfmonui.dll";
		*pcbOutputNeeded = sizeof(szUIDLL);
		if (cbOutputData < sizeof(szUIDLL))
			return ERROR_INSUFFICIENT_BUFFER;
		CopyMemory(pOutputData, szUIDLL, sizeof(szUIDLL));
		return ERROR_SUCCESS;
	}
	return ERROR_CAN_NOT_COMPLETE;
}
Ejemplo n.º 8
0
int main (int argc, char* argv[])
{
	
	DWORD			returned, needed, i;
	PPORT_INFO_1	buffer1 = NULL;
	PPORT_INFO_2	buffer2 = NULL;

	if (argc < 2)
	{
		fprintf (stderr, "useage: %s <servername>\n", argv[0]);
		exit (-1);
	}

	/* INFO LEVEL 1 */
	needed = returned = 0;
	EnumPorts(argv[1], 1, (LPBYTE)buffer1, 0, &needed, &returned);
	if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
	{
		fprintf (stderr, "Error getting port information for [%s] using NULL buffer.\n", argv[1]);
		exit (-1);
	}

	if ((buffer1 = (LPBYTE)malloc(needed)) == NULL)
	{
		fprintf (stderr, "Unable to malloc memory for PORT_INFO_1 buffer!\n");
		exit (-1);
	}
	if (!EnumPorts(argv[1], 1, (LPBYTE)buffer1, needed, &needed, &returned))
	{
		fprintf (stderr, "Error getting port information for [%s].\nSize of buffer = %d\n", 
			     argv[1], needed);
		exit (-1);
	}

	printf ("Port Info Level 1:\n");
	for (i=0; i<returned; i++)
	{
		printf ("\tPort Name\t= %s\n", buffer1[i].pName);
		printf ("\n");
	}
	free (buffer1);

	/* INFO LEVEL 2 */
	needed = returned = 0;
	EnumPorts(argv[1], 2, (LPBYTE)buffer2, 0, &needed, &returned);
	if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
	{
		fprintf (stderr, "Error getting port information for [%s] using NULL buffer.\n", argv[1], argv[2]);
		exit (-1);
	}

	if ((buffer2 = (LPBYTE)malloc(needed)) == NULL)
	{
		fprintf (stderr, "Unable to malloc memory for PORT_INFO_2 buffer!\n");
		exit (-1);
	}
	if (!EnumPorts(argv[1], 2, (LPBYTE)buffer2, needed, &needed, &returned))
	{
		fprintf (stderr, "Error getting port information for [%s].\nSize of buffer = %d\n", 
			     argv[1], needed);
		exit (-1);
	}

	printf ("Port Info Level 2:\n");
	for (i=0; i<returned; i++)
	{
		printf ("\tPort Name\t= %s\n",		buffer2[i].pPortName);
		printf ("\tMonitor Name\t= %s\n",	buffer2[i].pMonitorName);
		printf ("\tDescription\t= %s\n",	buffer2[i].pDescription);
		printf ("\tType\t\t= 0x%x\n",		buffer2[i].fPortType);
		printf ("\tReserved\t= %d\n",		buffer2[i].Reserved);
		printf ("\n");
	}
	free (buffer2);


	return 0;

}