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
;
26 PFILE_OBJECT FileObject
;
28 PKSIOBJECT_HEADER ObjectHeader
;
30 /* acquire parent file object */
31 Status
= ObReferenceObjectByHandle(ParentHandle
,
32 GENERIC_READ
| GENERIC_WRITE
,
33 IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
35 if (!NT_SUCCESS(Status
))
37 DPRINT("Failed to reference parent %x\n", Status
);
41 /* get parent object header */
42 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext
;
46 /* calculate request length */
48 Name
.MaximumLength
= wcslen(ObjectType
) * sizeof(WCHAR
) + CreateParametersSize
+ ObjectHeader
->ObjectClass
.MaximumLength
+ 2 * sizeof(WCHAR
);
49 Name
.MaximumLength
+= sizeof(WCHAR
);
50 /* acquire request buffer */
51 Name
.Buffer
= ExAllocatePool(NonPagedPool
, Name
.MaximumLength
);
52 /* check for success */
55 /* insufficient resources */
56 ObDereferenceObject(FileObject
);
57 return STATUS_INSUFFICIENT_RESOURCES
;
60 /* build a request which looks like \Parent\{ObjectGuid}\CreateParameters
61 * For pins the parent is the reference string used in registration
62 * For clocks it is full path for pin\{ClockGuid}\ClockCreateParams
65 RtlAppendUnicodeStringToString(&Name
, &ObjectHeader
->ObjectClass
);
66 RtlAppendUnicodeToString(&Name
, L
"\\");
67 RtlAppendUnicodeToString(&Name
, ObjectType
);
68 RtlAppendUnicodeToString(&Name
, L
"\\");
69 /* append create parameters */
70 RtlMoveMemory(Name
.Buffer
+ (Name
.Length
/ sizeof(WCHAR
)), CreateParameters
, CreateParametersSize
);
71 Name
.Length
+= CreateParametersSize
;
72 Name
.Buffer
[Name
.Length
/ 2] = L
'\0';
74 InitializeObjectAttributes(&ObjectAttributes
, &Name
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
, ParentHandle
, NULL
);
75 /* create the instance */
76 Status
= IoCreateFile(NodeHandle
,
84 FILE_SYNCHRONOUS_IO_NONALERT
,
89 IO_NO_PARAMETER_CHECKING
| IO_FORCE_ACCESS_CHECK
);
91 /* free request buffer */
92 ExFreePool(Name
.Buffer
);
93 /* release parent handle */
94 ObDereferenceObject(FileObject
);
102 KSDDKAPI NTSTATUS NTAPI
103 KsCreateTopologyNode(
104 IN HANDLE ParentHandle
,
105 IN PKSNODE_CREATE NodeCreate
,
106 IN ACCESS_MASK DesiredAccess
,
107 OUT PHANDLE NodeHandle
)
109 return KspCreateObjectType(ParentHandle
,
110 L
"{0621061A-EE75-11D0-B915-00A0C9223196}",
112 sizeof(KSNODE_CREATE
),
120 KSDDKAPI NTSTATUS NTAPI
121 KsValidateTopologyNodeCreateRequest(
123 IN PKSTOPOLOGY Topology
,
124 OUT PKSNODE_CREATE
* NodeCreate
)
127 return STATUS_UNSUCCESSFUL
;
136 KsTopologyPropertyHandler(
138 IN PKSPROPERTY Property
,
140 IN
const KSTOPOLOGY
* Topology
)
142 UNICODE_STRING LocalMachine
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\MediaCategories\\");
143 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"Name");
144 UNICODE_STRING GuidString
;
145 UNICODE_STRING KeyName
;
146 OBJECT_ATTRIBUTES ObjectAttributes
;
147 KSMULTIPLE_ITEM
* Item
;
149 PIO_STACK_LOCATION IoStack
;
153 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
155 if (Property
->Flags
!= KSPROPERTY_TYPE_GET
)
157 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
158 Irp
->IoStatus
.Information
= 0;
159 return STATUS_NOT_IMPLEMENTED
;
162 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
166 case KSPROPERTY_TOPOLOGY_CATEGORIES
:
167 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->CategoriesCount
* sizeof(GUID
);
168 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
170 Irp
->IoStatus
.Information
= Size
;
171 Status
= STATUS_BUFFER_TOO_SMALL
;
175 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
177 Item
->Count
= Topology
->CategoriesCount
;
179 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->Categories
, Topology
->CategoriesCount
* sizeof(GUID
));
180 Irp
->IoStatus
.Information
= Size
;
181 Status
= STATUS_SUCCESS
;
184 case KSPROPERTY_TOPOLOGY_NODES
:
185 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->TopologyNodesCount
* sizeof(GUID
);
186 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
188 Irp
->IoStatus
.Information
= Size
;
189 Status
= STATUS_BUFFER_TOO_SMALL
;
193 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
195 Item
->Count
= Topology
->TopologyNodesCount
;
197 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->TopologyNodes
, Topology
->TopologyNodesCount
* sizeof(GUID
));
198 Irp
->IoStatus
.Information
= Size
;
199 Status
= STATUS_SUCCESS
;
202 case KSPROPERTY_TOPOLOGY_CONNECTIONS
:
203 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->TopologyConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
);
204 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
206 Irp
->IoStatus
.Information
= Size
;
207 Status
= STATUS_BUFFER_TOO_SMALL
;
211 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
213 Item
->Count
= Topology
->TopologyConnectionsCount
;
215 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->TopologyConnections
, Topology
->TopologyConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
));
216 Irp
->IoStatus
.Information
= Size
;
217 Status
= STATUS_SUCCESS
;
220 case KSPROPERTY_TOPOLOGY_NAME
:
221 Node
= (KSP_NODE
*)Property
;
223 Status
= RtlStringFromGUID(&Topology
->TopologyNodesNames
[Node
->NodeId
], &GuidString
);
224 if (!NT_SUCCESS(Status
))
226 Irp
->IoStatus
.Information
= 0;
231 KeyName
.MaximumLength
= LocalMachine
.Length
+ GuidString
.Length
+ sizeof(WCHAR
);
232 KeyName
.Buffer
= ExAllocatePool(PagedPool
, KeyName
.MaximumLength
);
235 Irp
->IoStatus
.Information
= 0;
239 RtlAppendUnicodeStringToString(&KeyName
, &LocalMachine
);
240 RtlAppendUnicodeStringToString(&KeyName
, &GuidString
);
243 InitializeObjectAttributes(&ObjectAttributes
, &KeyName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
244 Status
= ZwOpenKey(&hKey
, GENERIC_READ
, &ObjectAttributes
);
246 if (!NT_SUCCESS(Status
))
248 DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status
);
249 ExFreePool(KeyName
.Buffer
);
250 Irp
->IoStatus
.Information
= 0;
253 ExFreePool(KeyName
.Buffer
);
254 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, NULL
, 0, &Size
);
255 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
)
258 Irp
->IoStatus
.Information
= 0;
262 KeyInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
) ExAllocatePool(NonPagedPool
, Size
);
265 Status
= STATUS_NO_MEMORY
;
269 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, (PVOID
)KeyInfo
, Size
, &Size
);
270 if (!NT_SUCCESS(Status
))
274 Irp
->IoStatus
.Information
= 0;
279 if (KeyInfo
->DataLength
+ sizeof(WCHAR
) > IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
281 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
282 Status
= STATUS_BUFFER_TOO_SMALL
;
287 RtlMoveMemory(Irp
->UserBuffer
, &KeyInfo
->Data
, KeyInfo
->DataLength
);
288 ((LPWSTR
)Irp
->UserBuffer
)[KeyInfo
->DataLength
/ sizeof(WCHAR
)] = L
'\0';
289 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
293 Irp
->IoStatus
.Information
= 0;
294 Status
= STATUS_NOT_IMPLEMENTED
;
303 KspTopologyPropertyHandler(
305 IN PKSIDENTIFIER Request
,
309 return STATUS_NOT_IMPLEMENTED
;