WdfDeviceCreateSymbolicLink for raw pdo

I am trying to create a PDO that will be accessed directly by a user-mode application. … However when the driver does WdfDeviceCreateSymbolicLink for the PDO it fails with error code 0xc0000184(STATUS_INVALID_DEVICE_STATE)… Not sure why the device is in invalid state here …Are there restrictions in creating a symbolic link for pdo ?..

Here is the snippet of the code…

DECLARE_CONST_UNICODE_STRING(deviceId, L"{GUID}\Drv Test\0");
DECLARE_CONST_UNICODE_STRING(hardwareId, L"TCHTST");
DECLARE_CONST_UNICODE_STRING(instanceId, L"0\0")
DECLARE_CONST_UNICODE_STRING(deviceName, L"\??\DrvTest");

//
// Create a child test PDO, where Device is the parent
//
deviceInit = WdfPdoInitAllocate(Device);

//
// Indicate this PDO runs in “raw mode”
//

if (NULL == deviceInit)
{
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error allocating WDFDEVICE_INIT structure”);

status = STATUS_INVALID_DEVICE_STATE;

goto exit;
}

status = WdfPdoInitAssignRawDevice(
deviceInit,
&GUID_DEVCLASS_HIDCLASS);

if (!NT_SUCCESS(status))
{
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error assigning test device object as raw device - %!STATUS!”,
status);

goto exit;
}

//
// Assign device, hardware, instance IDs
//
status = WdfPdoInitAssignDeviceID(
deviceInit,
&deviceId);

if (!NT_SUCCESS(status))
{
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error assigning test device ID - %!STATUS!”,
status);

goto exit;
}

status = WdfPdoInitAddHardwareID(
deviceInit,
&hardwareId);

if (!NT_SUCCESS(status))
{
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error assigning test device hardware ID - %!STATUS!”,
status);

goto exit;
}

status = WdfPdoInitAssignInstanceID(
deviceInit,
&instanceId);

if (!NT_SUCCESS(status))
{
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error assigning test device instance ID - %!STATUS!”,
status);

goto exit;
}

//
// test application has opened

WDF_FILEOBJECT_CONFIG_INIT(
&fileConfig,
TchSelfTestOnCreate,
TchSelfTestOnClose,
WDF_NO_EVENT_CALLBACK);

WdfDeviceInitSetFileObjectConfig(
deviceInit,
&fileConfig,
WDF_NO_OBJECT_ATTRIBUTES);

//
// Create the test device
//
WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes);

status = WdfDeviceCreate(
&deviceInit,
&objectAttributes,
&childDevice);

if (!NT_SUCCESS(status))
{
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error creating test device - %!STATUS!”,
status);

goto exit;
}

//
// Set up an I/O request queue so that calling application
// may send test requests to the device.
//
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
&queueConfig,
WdfIoQueueDispatchParallel);

queueConfig.EvtIoDeviceControl = TchSelfTestOnDeviceControl;

status = WdfIoQueueCreate(
childDevice,
&queueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&devContext->TestQueue);

if (!NT_SUCCESS(status))
{
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error creating test device request queue - %!STATUS!”,
status);

goto exit;
}

// Create a symbolic link name
status = WdfDeviceCreateSymbolicLink(childDevice, &deviceName);
if (!NT_SUCCESS(status)) {
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error creating Symbolic Name - %!STATUS!”,
status);

}

// called in addition to WdfPdoInitAllocate to
// associate the test PDO just created as child of the
// driver FDO
//
status = WdfFdoAddStaticChild(Device, childDevice);

if (!NT_SUCCESS(status))
{
Trace(
TRACE_LEVEL_ERROR,
TRACE_FLAG_INIT,
“Error adding test PDO as child of touch FDO - %!STATUS!”,
status);

goto exit;
}

=================================================