2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/topoology.c
5 * PURPOSE: KS Allocator functions
6 * PROGRAMMER: Johannes Anderwald
16 IN HANDLE ParentHandle
,
18 PVOID CreateParameters
,
19 UINT CreateParametersSize
,
20 IN ACCESS_MASK DesiredAccess
,
21 OUT PHANDLE NodeHandle
)
24 IO_STATUS_BLOCK IoStatusBlock
;
25 OBJECT_ATTRIBUTES ObjectAttributes
;
28 /* calculate request length */
30 Name
.MaximumLength
= wcslen(ObjectType
) * sizeof(WCHAR
) + CreateParametersSize
+ 2 * sizeof(WCHAR
);
31 Name
.MaximumLength
+= sizeof(WCHAR
);
32 /* acquire request buffer */
33 Name
.Buffer
= ExAllocatePool(NonPagedPool
, Name
.MaximumLength
);
34 /* check for success */
37 /* insufficient resources */
38 return STATUS_INSUFFICIENT_RESOURCES
;
41 /* build a request which looks like \{ObjectClass}\CreateParameters
42 * For pins the parent is the reference string used in registration
43 * For clocks it is full path for pin\{ClockGuid}\ClockCreateParams
45 RtlAppendUnicodeToString(&Name
, L
"\\");
46 RtlAppendUnicodeToString(&Name
, ObjectType
);
47 RtlAppendUnicodeToString(&Name
, L
"\\");
48 /* append create parameters */
49 RtlMoveMemory(Name
.Buffer
+ (Name
.Length
/ sizeof(WCHAR
)), CreateParameters
, CreateParametersSize
);
50 Name
.Length
+= CreateParametersSize
;
51 Name
.Buffer
[Name
.Length
/ 2] = L
'\0';
53 InitializeObjectAttributes(&ObjectAttributes
, &Name
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
, ParentHandle
, NULL
);
54 /* create the instance */
55 Status
= IoCreateFile(NodeHandle
,
68 IO_NO_PARAMETER_CHECKING
| IO_FORCE_ACCESS_CHECK
);
70 /* free request buffer */
71 ExFreePool(Name
.Buffer
);
79 KSDDKAPI NTSTATUS NTAPI
81 IN HANDLE ParentHandle
,
82 IN PKSNODE_CREATE NodeCreate
,
83 IN ACCESS_MASK DesiredAccess
,
84 OUT PHANDLE NodeHandle
)
86 return KspCreateObjectType(ParentHandle
,
87 KSSTRING_TopologyNode
,
89 sizeof(KSNODE_CREATE
),
100 KsValidateTopologyNodeCreateRequest(
102 IN PKSTOPOLOGY Topology
,
103 OUT PKSNODE_CREATE
* OutNodeCreate
)
105 PKSNODE_CREATE NodeCreate
;
109 /* did the caller miss the topology */
111 return STATUS_INVALID_PARAMETER
;
113 /* set create param size */
114 Size
= sizeof(KSNODE_CREATE
);
116 /* fetch create parameters */
117 Status
= KspCopyCreateRequest(Irp
,
118 KSSTRING_TopologyNode
,
120 (PVOID
*)&NodeCreate
);
122 if (!NT_SUCCESS(Status
))
125 if (NodeCreate
->CreateFlags
!= 0 || (NodeCreate
->Node
>= Topology
->TopologyNodesCount
&& NodeCreate
->Node
!= (ULONG
)-1))
127 /* invalid node create */
128 FreeItem(NodeCreate
);
129 return STATUS_UNSUCCESSFUL
;
133 *OutNodeCreate
= NodeCreate
;
144 KsTopologyPropertyHandler(
146 IN PKSPROPERTY Property
,
148 IN
const KSTOPOLOGY
* Topology
)
150 UNICODE_STRING LocalMachine
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\MediaCategories\\");
151 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"Name");
152 UNICODE_STRING GuidString
;
153 UNICODE_STRING KeyName
;
154 OBJECT_ATTRIBUTES ObjectAttributes
;
155 KSMULTIPLE_ITEM
* Item
;
157 PIO_STACK_LOCATION IoStack
;
161 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
163 if (Property
->Flags
!= KSPROPERTY_TYPE_GET
)
165 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
166 Irp
->IoStatus
.Information
= 0;
167 return STATUS_NOT_IMPLEMENTED
;
170 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
174 case KSPROPERTY_TOPOLOGY_CATEGORIES
:
175 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->CategoriesCount
* sizeof(GUID
);
176 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
178 Irp
->IoStatus
.Information
= Size
;
179 Status
= STATUS_BUFFER_TOO_SMALL
;
183 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
185 Item
->Count
= Topology
->CategoriesCount
;
187 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->Categories
, Topology
->CategoriesCount
* sizeof(GUID
));
188 Irp
->IoStatus
.Information
= Size
;
189 Status
= STATUS_SUCCESS
;
192 case KSPROPERTY_TOPOLOGY_NODES
:
193 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->TopologyNodesCount
* sizeof(GUID
);
194 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
196 Irp
->IoStatus
.Information
= Size
;
197 Status
= STATUS_BUFFER_TOO_SMALL
;
201 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
203 Item
->Count
= Topology
->TopologyNodesCount
;
205 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->TopologyNodes
, Topology
->TopologyNodesCount
* sizeof(GUID
));
206 Irp
->IoStatus
.Information
= Size
;
207 Status
= STATUS_SUCCESS
;
210 case KSPROPERTY_TOPOLOGY_CONNECTIONS
:
211 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->TopologyConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
);
212 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
214 Irp
->IoStatus
.Information
= Size
;
215 Status
= STATUS_BUFFER_TOO_SMALL
;
219 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
221 Item
->Count
= Topology
->TopologyConnectionsCount
;
223 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->TopologyConnections
, Topology
->TopologyConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
));
224 Irp
->IoStatus
.Information
= Size
;
225 Status
= STATUS_SUCCESS
;
228 case KSPROPERTY_TOPOLOGY_NAME
:
229 Node
= (KSP_NODE
*)Property
;
231 Status
= RtlStringFromGUID(&Topology
->TopologyNodesNames
[Node
->NodeId
], &GuidString
);
232 if (!NT_SUCCESS(Status
))
234 Irp
->IoStatus
.Information
= 0;
239 KeyName
.MaximumLength
= LocalMachine
.Length
+ GuidString
.Length
+ sizeof(WCHAR
);
240 KeyName
.Buffer
= ExAllocatePool(PagedPool
, KeyName
.MaximumLength
);
243 Irp
->IoStatus
.Information
= 0;
247 RtlAppendUnicodeStringToString(&KeyName
, &LocalMachine
);
248 RtlAppendUnicodeStringToString(&KeyName
, &GuidString
);
251 InitializeObjectAttributes(&ObjectAttributes
, &KeyName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
252 Status
= ZwOpenKey(&hKey
, GENERIC_READ
, &ObjectAttributes
);
254 if (!NT_SUCCESS(Status
))
256 DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status
);
257 ExFreePool(KeyName
.Buffer
);
258 Irp
->IoStatus
.Information
= 0;
261 ExFreePool(KeyName
.Buffer
);
262 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, NULL
, 0, &Size
);
263 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
)
266 Irp
->IoStatus
.Information
= 0;
270 KeyInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
) ExAllocatePool(NonPagedPool
, Size
);
273 Status
= STATUS_NO_MEMORY
;
277 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, (PVOID
)KeyInfo
, Size
, &Size
);
278 if (!NT_SUCCESS(Status
))
282 Irp
->IoStatus
.Information
= 0;
287 if (KeyInfo
->DataLength
+ sizeof(WCHAR
) > IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
289 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
290 Status
= STATUS_BUFFER_TOO_SMALL
;
295 RtlMoveMemory(Irp
->UserBuffer
, &KeyInfo
->Data
, KeyInfo
->DataLength
);
296 ((LPWSTR
)Irp
->UserBuffer
)[KeyInfo
->DataLength
/ sizeof(WCHAR
)] = L
'\0';
297 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
301 Irp
->IoStatus
.Information
= 0;
302 Status
= STATUS_NOT_IMPLEMENTED
;
311 KspTopologyPropertyHandler(
313 IN PKSIDENTIFIER Request
,
317 return STATUS_NOT_IMPLEMENTED
;