めいくりぷとのブログ

技術的なことやゲームのことやら・・・

ドライバ

_Success_(NT_SUCCESS(return))
NTSTATUS
NTAPI
ZwOpenDriver(
	_In_  PUNICODE_STRING DeviceName,
	_Out_ PHANDLE		  DeviceHandle
	)
{
	HANDLE Device;

	if (!DeviceName || !DeviceHandle)
		return STATUS_INVALID_PARAMETER;

	Device = CreateFile(DeviceName->Buffer,
		GENERIC_READ | GENERIC_WRITE | FILE_GENERIC_EXECUTE,
		0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, 0);

	if (Device != NULL &&
		Device != INVALID_HANDLE_VALUE)
	{
		*DeviceHandle = Device;
		return STATUS_SUCCESS;
	}

	return STATUS_UNSUCCESSFUL;
}

_Success_(NT_SUCCESS(return))
NTSTATUS
NTAPI
ZwCloseDriver(
	_In_ HANDLE DeviceHandle
	)
{
	return NtClose(DeviceHandle);
}

_Success_(NT_SUCCESS(return))
NTSTATUS
NTAPI
ZwStartDriver(
	_In_  PUNICODE_STRING DeviceName,
	_In_  PUNICODE_STRING DeviceDosName,
	_Out_ PHANDLE		  DeviceHandle
	)
{
	SC_HANDLE SCManager;
	SC_HANDLE ServiceHandle;
	HANDLE Device;

	if (!DeviceName || !DeviceDosName || !DeviceHandle)
		return STATUS_INVALID_PARAMETER;

	SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	ServiceHandle = OpenService(SCManager, DeviceName->Buffer, SERVICE_ALL_ACCESS);

	if (ServiceHandle == NULL)
	{
		ServiceHandle = CreateService(SCManager, DeviceName->Buffer, DeviceName->Buffer, 
			SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
			SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
			DeviceName->Buffer, NULL, NULL, NULL, NULL, NULL);

		if (ServiceHandle == NULL)
		{
			CloseServiceHandle(SCManager);
			return STATUS_INVALID_HANDLE;
		}
	}

	if (StartService(ServiceHandle, 0, NULL) == FALSE)
	{
		ULONG ErrorCode = GetLastError();
		if (ErrorCode != ERROR_SERVICE_ALREADY_RUNNING)
		{
			DeleteService(ServiceHandle);
			CloseServiceHandle(ServiceHandle);
			CloseServiceHandle(SCManager);
			return NULL;
		}
	}

	Device = CreateFile(DeviceDosName->Buffer, GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
		OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

	if (Device == INVALID_HANDLE_VALUE)
	{
		SERVICE_STATUS ServiceStatus = { 0 };
		ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus);
		return STATUS_INVALID_HANDLE;
	}	

	*DeviceHandle = Device;
	CloseServiceHandle(ServiceHandle);
	CloseServiceHandle(SCManager);	

	return STATUS_SUCCESS;
}

_Success_(NT_SUCCESS(return))
NTSTATUS
NTAPI
ZwStopDriver(
	_In_ PUNICODE_STRING DeviceName
	)
{
	SC_HANDLE SCManager;
	SC_HANDLE ServiceHandle;
	NTSTATUS Status;

	if (!DeviceName)
		return STATUS_INVALID_PARAMETER;

	SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	ServiceHandle = OpenService(SCManager, DeviceName->Buffer, SERVICE_ALL_ACCESS);

	SERVICE_STATUS ServiceStatus = { 0 };
	ControlService(ServiceHandle, SERVICE_CONTROL_STOP, &ServiceStatus);

	Status = STATUS_UNSUCCESSFUL;
	if (DeleteService(ServiceHandle))
		Status = STATUS_SUCCESS;

	CloseServiceHandle(ServiceHandle);
	CloseServiceHandle(SCManager);

	return Status;
}