I have following method defined in one of my headers :
typedef struct _BEEP_SET_PARAMETERS {
ULONG Frequency;
ULONG Duration;
} BEEP_SET_PARAMETERS, * PBEEP_SET_PARAMETERS;
inline void DoBeepIoctl()
{
UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\\Device\\Beep");
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes, &deviceName, NULL, NULL, NULL);
HANDLE beepDriver;
IO_STATUS_BLOCK IoStatus;
NTSTATUS status = ZwOpenFile(&beepDriver, 0, &objectAttributes, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN);
if (!beepDriver)
{
Print("Initialization failed !");
return;
}
if (status == STATUS_SUCCESS)
{
ULONG IOCTL_BEEP = CTL_CODE(FILE_DEVICE_BEEP, 0, METHOD_BUFFERED, FILE_ANY_ACCESS);
ULONG returned = 0;
BEEP_SET_PARAMETERS BeepSettings;
BeepSettings.Duration = 1000;
BeepSettings.Frequency = 500;
status = ZwDeviceIoControlFile(beepDriver, NULL, NULL, NULL, &IoStatus, IOCTL_BEEP, &BeepSettings, sizeof(BeepSettings), &returned, 0);
Print("ZwDeviceIoControlFile status is %X", status);
}
else
{
Print("status is not success %X", status);
}
}
When I call directly from driver entry like this :
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(DriverObject);
UNREFERENCED_PARAMETER(RegistryPath);
Print("Beep");
DoBeepIoctl();
}
It exectues properly.
However when I call it from thread spawned via PsCreateSystemThread it return status NTSTATUS 0x00000103 which is equal to STATUS_PENDING and no beep is ever heard.
Thread creation snippet looks like this :
HANDLE threadHandle = NULL;
NTSTATUS status = PsCreateSystemThread(&threadHandle, GENERIC_ALL, NULL, NULL, NULL, (PKSTART_ROUTINE)start, NULL);
And last but not least the thread routine itself :
void MainThread()
{
Print("Do the beep");
DoBeepIoctl();
}
Question is what am I missing to call Beep.sys IOCTL successfully from spawned thread ?