332 lines
9.6 KiB
C++
332 lines
9.6 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2001 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// tdilib.cpp
|
|
//
|
|
// Abstract:
|
|
// tdilib initialization and shutdown functions
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "winsvc.h"
|
|
|
|
//
|
|
// library global variables are defined here
|
|
//
|
|
HANDLE hTdiSampleDriver; // handle used to call driver
|
|
CRITICAL_SECTION LibCriticalSection; // serialize DeviceIoControl calls...
|
|
|
|
|
|
// ----------------------------------------------
|
|
//
|
|
// Function: TdiLibInit
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: TRUE -- everything initialized ok
|
|
// FALSE -- initialization error (usually, unable to attach driver)
|
|
//
|
|
// Descript: This function is called by the by the exe to
|
|
// initialize communication with the driver. It loads the
|
|
// driver, and establishes communication with it
|
|
//
|
|
// ----------------------------------------------
|
|
|
|
BOOLEAN
|
|
TdiLibInit(VOID)
|
|
{
|
|
//
|
|
// the handle to tdisample.sys should always be null on entry
|
|
// Complain loadly if it is not.
|
|
//
|
|
if (hTdiSampleDriver != NULL)
|
|
{
|
|
OutputDebugString(TEXT("hTdiSampleDriver non-null on entry!\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// find out what operating system we are using.
|
|
//
|
|
OSVERSIONINFO OsVersionInfo;
|
|
|
|
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
if (GetVersionEx(&OsVersionInfo))
|
|
{
|
|
if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
if (OsVersionInfo.dwMajorVersion < 5)
|
|
{
|
|
OutputDebugString(TEXT("Not supported for versions prior to Windows 2000\n"));
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OutputDebugString(TEXT("Unrecognized OS version\n"));
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OutputDebugString(TEXT("Cannot get OS version -- aborting\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// assume tdisample.sys driver is loaded -- try to attach it
|
|
// normally driver will be loaded
|
|
//
|
|
hTdiSampleDriver = CreateFile(TEXT("\\\\.\\TDISAMPLE"),
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, // lpSecurityAttirbutes
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
NULL); // lpTemplateFile
|
|
//
|
|
// If the driver is not loaded, then we have to try and load it...
|
|
//
|
|
if (hTdiSampleDriver == INVALID_HANDLE_VALUE)
|
|
{
|
|
OutputDebugString(TEXT("Tdisample.sys not loaded. Attempting to load\n"));
|
|
|
|
SC_HANDLE hSCMan = NULL;
|
|
SC_HANDLE hDriver = NULL;
|
|
|
|
if ((hSCMan = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL)
|
|
{
|
|
OutputDebugString(TEXT("Failed to Open ServiceManager\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// open service
|
|
//
|
|
if((hDriver = OpenService(hSCMan, TEXT("tdisample"), SERVICE_ALL_ACCESS)) == NULL)
|
|
{
|
|
//
|
|
// service doesn't exist -- try to create it
|
|
//
|
|
OutputDebugString(TEXT("Service does not exist -- try to create it"));
|
|
hDriver = CreateService(hSCMan,
|
|
TEXT("tdisample"),
|
|
TEXT("tdisample"),
|
|
SERVICE_ALL_ACCESS,
|
|
SERVICE_KERNEL_DRIVER,
|
|
SERVICE_DEMAND_START,
|
|
SERVICE_ERROR_NORMAL,
|
|
TEXT("\\SystemRoot\\system32\\drivers\\tdisample.sys"),
|
|
NULL, NULL, NULL, NULL, NULL);
|
|
}
|
|
|
|
if (hDriver != NULL)
|
|
{
|
|
SERVICE_STATUS ServiceStatus;
|
|
|
|
if(QueryServiceStatus(hDriver, &ServiceStatus))
|
|
{
|
|
if(ServiceStatus.dwServiceType != SERVICE_KERNEL_DRIVER)
|
|
{
|
|
CloseServiceHandle(hDriver);
|
|
CloseServiceHandle(hSCMan);
|
|
return FALSE;
|
|
}
|
|
|
|
switch(ServiceStatus.dwCurrentState)
|
|
{
|
|
//
|
|
// this is the one we expect! try and start it
|
|
//
|
|
case SERVICE_STOPPED:
|
|
{
|
|
int i;
|
|
|
|
if(!StartService(hDriver, 0, NULL))
|
|
{
|
|
CloseServiceHandle(hDriver);
|
|
CloseServiceHandle(hSCMan);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// we need to make sure tdisample.sys is actually running
|
|
//
|
|
for(i=0; i < 30; i++)
|
|
{
|
|
Sleep(500);
|
|
if(QueryServiceStatus(hDriver, &ServiceStatus))
|
|
{
|
|
if(ServiceStatus.dwCurrentState == SERVICE_RUNNING)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
|
|
{
|
|
OutputDebugString(TEXT("Failed to start tdisample service\n"));
|
|
CloseServiceHandle(hDriver);
|
|
CloseServiceHandle(hSCMan);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
//
|
|
// we don't expect this, but (technically) it is not an error
|
|
// If it happens, just assume that the load succeeded
|
|
//
|
|
case SERVICE_RUNNING:
|
|
OutputDebugString(TEXT("ServiceStatus thinks driver is running\n"));
|
|
break;
|
|
|
|
//
|
|
// anything else is an error
|
|
//
|
|
default:
|
|
OutputDebugString(TEXT("ServiceStatusError\n"));
|
|
CloseServiceHandle(hDriver);
|
|
CloseServiceHandle(hSCMan);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OutputDebugString(TEXT("QueryServiceStatus failed\n"));
|
|
CloseServiceHandle(hDriver);
|
|
CloseServiceHandle(hSCMan);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OutputDebugString(TEXT("Tdisample service does not exist!\n"));
|
|
CloseServiceHandle(hSCMan);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// if get to here, system thinks it is loaded. So try again
|
|
//
|
|
hTdiSampleDriver = CreateFile(TEXT("\\\\.\\TDISAMPLE"),
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, // lpSecurityAttirbutes
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
NULL); // lpTemplateFile
|
|
|
|
//
|
|
// if fails again, give up
|
|
//
|
|
if (hTdiSampleDriver == INVALID_HANDLE_VALUE)
|
|
{
|
|
OutputDebugString(TEXT("Unable to load Tdisample.sys\n"));
|
|
hTdiSampleDriver = NULL;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// if get to here, tdisample.sys is loaded, and hTdiSampleDriver is valid
|
|
//
|
|
try
|
|
{
|
|
InitializeCriticalSection(&LibCriticalSection);
|
|
}
|
|
catch(...)
|
|
{
|
|
CloseHandle(hTdiSampleDriver);
|
|
hTdiSampleDriver = NULL;
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// make sure the dll and driver are the same version (ie, are compatible)
|
|
//
|
|
{
|
|
NTSTATUS lStatus; // status of command
|
|
ULONG ulVersion = 0; // default value (error)
|
|
RECEIVE_BUFFER ReceiveBuffer; // return info from command
|
|
SEND_BUFFER SendBuffer; // arguments for command
|
|
|
|
//
|
|
// call driver to execute command
|
|
//
|
|
lStatus = TdiLibDeviceIO(ulVERSION_CHECK,
|
|
&SendBuffer,
|
|
&ReceiveBuffer);
|
|
|
|
if (lStatus == STATUS_SUCCESS)
|
|
{
|
|
ulVersion = ReceiveBuffer.RESULTS.ulReturnValue;
|
|
}
|
|
|
|
//
|
|
// check results..
|
|
//
|
|
if (ulVersion == TDI_SAMPLE_VERSION_ID)
|
|
{
|
|
return TRUE; // only successful completion!!!
|
|
}
|
|
else
|
|
{
|
|
OutputDebugString(TEXT("Incompatible driver version.\n"));
|
|
}
|
|
|
|
//
|
|
// if get to here, had an error and need to clean up
|
|
//
|
|
DeleteCriticalSection(&LibCriticalSection);
|
|
CloseHandle(hTdiSampleDriver);
|
|
hTdiSampleDriver = NULL;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// ----------------------------------------------
|
|
//
|
|
// Function: TdiLibClose
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: none
|
|
//
|
|
// Descript: This function is called by the by the dll or exe to
|
|
// shut down communication with the driver.
|
|
//
|
|
// ----------------------------------------------
|
|
|
|
VOID
|
|
TdiLibClose(VOID)
|
|
{
|
|
//
|
|
// need to check for NULL since function will be called
|
|
// if the open above failed..
|
|
//
|
|
if (hTdiSampleDriver != NULL)
|
|
{
|
|
DeleteCriticalSection(&LibCriticalSection);
|
|
|
|
//
|
|
// close the connection to tdisample.sys
|
|
//
|
|
if (!CloseHandle(hTdiSampleDriver))
|
|
{
|
|
OutputDebugString(TEXT("\n TdiLibClose: closehandle failed\n"));
|
|
}
|
|
hTdiSampleDriver = NULL;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// end of file tdilib.cpp
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|