 /*++
*******************************************************************************
* Copyright (c) 1990-97 Digi International Inc., All Rights Reserved          *
*                                                                             *
* This software contains proprietary and confidential information of Digi     *
* International Inc.  By accepting transfer of this copy, Recipient agrees    *
* to retain this software in confidence, to prevent disclosure to others,     *
* and to make no use of this software other than that for which it was        *
* delivered.  This is an unpublished copyrighted work of Digi International   *
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly   *
* prohibited.                                                                 *
*                                                                             *
* Restricted Rights Legend                                                    *
*                                                                             *
* Use, duplication, or disclosure by the Government is subject to             *
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in         *
* Technical Data and Computer Software clause at DFARS 252.227-7031 or        *
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -          *
* Restricted Rights at 48 CFR 52.227-19, as applicable.                       *
*                                                                             *
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343          *
*                                                                             *
*******************************************************************************

Module Name:

   DigiPci.c

Abstract:

   This program is a win32 DLL which exercises the DigiPci driver.

   It performs the following tasks: 
      - start the driver service
      - send the ioctl request to get pci data
      - stop the driver

--*/

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
#include <crtdbg.h>

#include "detect.h"
#include "detectpci.h"


static BOOL StartDriver(void)
{
   BOOLEAN fSuccess = FALSE;

   SC_HANDLE hScManager = NULL;
   SC_HANDLE hService = NULL;

   hScManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
   if (hScManager == NULL)
   {
      DebugOutput(TEXT("OpenSCManager failed, GetLastError 0x%x\n"), GetLastError());
      goto Exit;
   }
   
   hService = OpenService(hScManager, DIGIPCI_DEVICENAME, SERVICE_ALL_ACCESS);
   if (hService == NULL)
   {
      DebugOutput(TEXT("OpenService failed, GetLastError 0x%x\n"), GetLastError());
      goto Exit;
   }

   if (!StartService(hService, 0, NULL))
   {
      DebugOutput(TEXT("StartService failed, GetLastError 0x%x\n"), GetLastError());
      goto Exit;
   }

   fSuccess = TRUE;

Exit:
   if (hScManager != NULL)
      CloseServiceHandle(hScManager);

   if (hService != NULL)
      CloseServiceHandle(hService);

   return fSuccess;
}


static void StopDriver(void)
{
   SC_HANDLE hScManager = NULL;
   SC_HANDLE hService = NULL;
   SERVICE_STATUS Status = {0};

   hScManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
   if (hScManager == NULL)
   {
      DebugOutput(TEXT("OpenSCManager failed, GetLastError 0x%x\n"), GetLastError());
      goto Exit;
   }
   
   hService = OpenService(hScManager, DIGIPCI_DEVICENAME, SERVICE_ALL_ACCESS);
   if (hService == NULL)
   {
      DebugOutput(TEXT("OpenService failed, GetLastError 0x%x\n"), GetLastError());
      goto Exit;
   }

   if (!ControlService(hService, SERVICE_CONTROL_STOP, &Status))
   {
      DebugOutput(TEXT("ControlService failed, GetLastError 0x%x\n"), GetLastError());
      goto Exit;
   }

Exit:
   if (hScManager != NULL)
      CloseServiceHandle(hScManager);

   if (hService != NULL)
      CloseServiceHandle(hService);

   return;
}


extern BOOL WINAPI DetectPCI(DWORD const BusNumber, DWORD const SlotNumber, DIGI_PCI_DATA * const pPciData)
{
   BOOLEAN fSuccess = FALSE;

   HANDLE hFile = NULL;
   DWORD cb = 0;

   _ASSERTE(pPciData != NULL);
   if (pPciData == NULL)
   {
      DebugOutput(TEXT("Invalid parameter, pPciData == NULL!\n"));
      goto Exit;
   }

   if (!StartDriver())
   {
      DebugOutput(TEXT("StartDriver() failed\n"));
      goto Exit;
   }

   hFile = CreateFile(TEXT("\\\\.\\")DIGIPCI_DEVICENAME, GENERIC_READ | GENERIC_WRITE,  
                      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 
                      FILE_ATTRIBUTE_NORMAL, NULL);
   if (hFile == NULL)
   {
      DebugOutput(TEXT("CreateFile failed, GetLastError 0x%x\n"), GetLastError());
      goto Exit;
   }
   
   pPciData->BusNumber  = BusNumber;
   pPciData->SlotNumber = SlotNumber;

   if (!DeviceIoControl(hFile, IOCTL_DIGIPCI_GET_DATA, pPciData, sizeof(*pPciData), 
                        pPciData, sizeof(*pPciData), &cb, NULL))
   {
      DebugOutput(TEXT("DeviceIoControl failed, GetLastError 0x%x\n"), GetLastError());
      goto Exit;
   }

   DebugOutput(TEXT("PciData:\n")
               TEXT("   BusNumber   0x%x\n")
               TEXT("   SlotNumber  0x%x\n")
               TEXT("   VendorId    0x%x\n")
               TEXT("   DeviceId    0x%x\n")
               TEXT("   SubVendorId 0x%x\n")
               TEXT("   SubSystemId 0x%x\n")
               TEXT("   RevisionId  0x%x\n"),
               pPciData->BusNumber, pPciData->SlotNumber, 
               pPciData->VendorId, pPciData->DeviceId, pPciData->SubVendorId, 
               pPciData->SubSystemId, pPciData->RevisionId);

   fSuccess = TRUE;

Exit:
   if (hFile != NULL)
      CloseHandle(hFile);

   StopDriver();

   return fSuccess;
}
