3 /* ===============================================================
10 IN HANDLE ParentHandle
,
12 PVOID CreateParameters
,
13 UINT CreateParametersSize
,
14 IN ACCESS_MASK DesiredAccess
,
15 OUT PHANDLE NodeHandle
)
18 IO_STATUS_BLOCK IoStatusBlock
;
19 OBJECT_ATTRIBUTES ObjectAttributes
;
20 PFILE_OBJECT FileObject
;
22 PKSIOBJECT_HEADER ObjectHeader
;
24 /* acquire parent file object */
25 Status
= ObReferenceObjectByHandle(ParentHandle
,
26 GENERIC_READ
| GENERIC_WRITE
,
27 IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
29 if (!NT_SUCCESS(Status
))
31 DPRINT("Failed to reference parent %x\n", Status
);
35 /* get parent object header */
36 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext
;
40 /* calculate request length */
42 Name
.MaximumLength
= wcslen(ObjectType
) * sizeof(WCHAR
) + CreateParametersSize
+ ObjectHeader
->ObjectClass
.MaximumLength
+ 2 * sizeof(WCHAR
);
43 Name
.MaximumLength
+= sizeof(WCHAR
);
44 /* acquire request buffer */
45 Name
.Buffer
= ExAllocatePool(NonPagedPool
, Name
.MaximumLength
);
46 /* check for success */
49 /* insufficient resources */
50 ObDereferenceObject(FileObject
);
51 return STATUS_INSUFFICIENT_RESOURCES
;
54 /* build a request which looks like \Parent\{ObjectGuid}\CreateParameters
55 * For pins the parent is the reference string used in registration
56 * For clocks it is full path for pin\{ClockGuid}\ClockCreateParams
59 RtlAppendUnicodeStringToString(&Name
, &ObjectHeader
->ObjectClass
);
60 RtlAppendUnicodeToString(&Name
, L
"\\");
61 RtlAppendUnicodeToString(&Name
, ObjectType
);
62 RtlAppendUnicodeToString(&Name
, L
"\\");
63 /* append create parameters */
64 RtlMoveMemory(Name
.Buffer
+ (Name
.Length
/ sizeof(WCHAR
)), CreateParameters
, CreateParametersSize
);
65 Name
.Length
+= CreateParametersSize
;
66 Name
.Buffer
[Name
.Length
/ 2] = L
'\0';
68 InitializeObjectAttributes(&ObjectAttributes
, &Name
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
, ParentHandle
, NULL
);
69 /* create the instance */
70 Status
= IoCreateFile(NodeHandle
,
78 FILE_SYNCHRONOUS_IO_NONALERT
,
83 IO_NO_PARAMETER_CHECKING
| IO_FORCE_ACCESS_CHECK
);
85 /* free request buffer */
86 ExFreePool(Name
.Buffer
);
87 /* release parent handle */
88 ObDereferenceObject(FileObject
);
96 KSDDKAPI NTSTATUS NTAPI
98 IN HANDLE ParentHandle
,
99 IN PKSNODE_CREATE NodeCreate
,
100 IN ACCESS_MASK DesiredAccess
,
101 OUT PHANDLE NodeHandle
)
103 return KspCreateObjectType(ParentHandle
,
104 L
"{0621061A-EE75-11D0-B915-00A0C9223196}",
106 sizeof(KSNODE_CREATE
),
114 KSDDKAPI NTSTATUS NTAPI
115 KsValidateTopologyNodeCreateRequest(
117 IN PKSTOPOLOGY Topology
,
118 OUT PKSNODE_CREATE
* NodeCreate
)
121 return STATUS_UNSUCCESSFUL
;
130 KsTopologyPropertyHandler(
132 IN PKSPROPERTY Property
,
134 IN
const KSTOPOLOGY
* Topology
)
136 UNICODE_STRING LocalMachine
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\MediaCategories\\");
137 UNICODE_STRING Name
= RTL_CONSTANT_STRING(L
"Name");
138 UNICODE_STRING GuidString
;
139 UNICODE_STRING KeyName
;
140 OBJECT_ATTRIBUTES ObjectAttributes
;
141 KSMULTIPLE_ITEM
* Item
;
143 PIO_STACK_LOCATION IoStack
;
147 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo
;
149 if (Property
->Flags
!= KSPROPERTY_TYPE_GET
)
151 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
152 Irp
->IoStatus
.Information
= 0;
153 return STATUS_NOT_IMPLEMENTED
;
156 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
160 case KSPROPERTY_TOPOLOGY_CATEGORIES
:
161 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->CategoriesCount
* sizeof(GUID
);
162 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
164 Irp
->IoStatus
.Information
= Size
;
165 Status
= STATUS_BUFFER_TOO_SMALL
;
169 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
171 Item
->Count
= Topology
->CategoriesCount
;
173 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->Categories
, Topology
->CategoriesCount
* sizeof(GUID
));
174 Irp
->IoStatus
.Information
= Size
;
175 Status
= STATUS_SUCCESS
;
178 case KSPROPERTY_TOPOLOGY_NODES
:
179 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->TopologyNodesCount
* sizeof(GUID
);
180 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
182 Irp
->IoStatus
.Information
= Size
;
183 Status
= STATUS_BUFFER_TOO_SMALL
;
187 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
189 Item
->Count
= Topology
->TopologyNodesCount
;
191 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->TopologyNodes
, Topology
->TopologyNodesCount
* sizeof(GUID
));
192 Irp
->IoStatus
.Information
= Size
;
193 Status
= STATUS_SUCCESS
;
196 case KSPROPERTY_TOPOLOGY_CONNECTIONS
:
197 Size
= sizeof(KSMULTIPLE_ITEM
) + Topology
->TopologyConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
);
198 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< Size
)
200 Irp
->IoStatus
.Information
= Size
;
201 Status
= STATUS_BUFFER_TOO_SMALL
;
205 Item
= (KSMULTIPLE_ITEM
*)Irp
->UserBuffer
;
207 Item
->Count
= Topology
->TopologyConnectionsCount
;
209 RtlMoveMemory((PVOID
)(Item
+ 1), (PVOID
)Topology
->TopologyConnections
, Topology
->TopologyConnectionsCount
* sizeof(KSTOPOLOGY_CONNECTION
));
210 Irp
->IoStatus
.Information
= Size
;
211 Status
= STATUS_SUCCESS
;
214 case KSPROPERTY_TOPOLOGY_NAME
:
215 Node
= (KSP_NODE
*)Property
;
217 Status
= RtlStringFromGUID(&Topology
->TopologyNodesNames
[Node
->NodeId
], &GuidString
);
218 if (!NT_SUCCESS(Status
))
220 Irp
->IoStatus
.Information
= 0;
225 KeyName
.MaximumLength
= LocalMachine
.Length
+ GuidString
.Length
+ sizeof(WCHAR
);
226 KeyName
.Buffer
= ExAllocatePool(PagedPool
, KeyName
.MaximumLength
);
229 Irp
->IoStatus
.Information
= 0;
233 RtlAppendUnicodeStringToString(&KeyName
, &LocalMachine
);
234 RtlAppendUnicodeStringToString(&KeyName
, &GuidString
);
237 InitializeObjectAttributes(&ObjectAttributes
, &KeyName
, OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
238 Status
= ZwOpenKey(&hKey
, GENERIC_READ
, &ObjectAttributes
);
240 if (!NT_SUCCESS(Status
))
242 DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status
);
243 ExFreePool(KeyName
.Buffer
);
244 Irp
->IoStatus
.Information
= 0;
247 ExFreePool(KeyName
.Buffer
);
248 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, NULL
, 0, &Size
);
249 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_TOO_SMALL
)
252 Irp
->IoStatus
.Information
= 0;
256 KeyInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
) ExAllocatePool(NonPagedPool
, Size
);
259 Status
= STATUS_NO_MEMORY
;
263 Status
= ZwQueryValueKey(hKey
, &Name
, KeyValuePartialInformation
, (PVOID
)KeyInfo
, Size
, &Size
);
264 if (!NT_SUCCESS(Status
))
268 Irp
->IoStatus
.Information
= 0;
273 if (KeyInfo
->DataLength
+ sizeof(WCHAR
) > IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
275 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
276 Status
= STATUS_BUFFER_TOO_SMALL
;
281 RtlMoveMemory(Irp
->UserBuffer
, &KeyInfo
->Data
, KeyInfo
->DataLength
);
282 ((LPWSTR
)Irp
->UserBuffer
)[KeyInfo
->DataLength
/ sizeof(WCHAR
)] = L
'\0';
283 Irp
->IoStatus
.Information
= KeyInfo
->DataLength
+ sizeof(WCHAR
);
287 Irp
->IoStatus
.Information
= 0;
288 Status
= STATUS_NOT_IMPLEMENTED
;