ReactOS 0.4.15-dev-7788-g1ad9096
swenum.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/swenum.c
5 * PURPOSE: KS Software BUS functions
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9#include "precomp.h"
10
11#include <stdio.h>
12#include <swenum.h>
13
14#define NDEBUG
15#include <debug.h>
16
18
21 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
22 IN PBUS_DEVICE_ENTRY DummyEntry,
23 IN LPWSTR RootName,
24 IN LPWSTR DirectoryName);
25
28 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
29 IN PBUS_DEVICE_ENTRY DeviceEntry,
30 OUT PDEVICE_OBJECT * OutDeviceObject)
31{
33 WCHAR Buffer[50];
34 ULONG CurDeviceId;
37 PCOMMON_DEVICE_EXTENSION DeviceExtension;
38
39 /* increment device count */
40 CurDeviceId = InterlockedIncrement(&KsDeviceCount);
41
42 /* generate new device id */
43 swprintf(Buffer, L"\\Device\\KSENUM%08x", CurDeviceId);
44
45 /* initialize new device name */
47
48 /* create new device object */
49 Status = IoCreateDevice(BusDeviceExtension->BusDeviceObject->DriverObject, sizeof(PVOID), &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
50
51 /* check for success */
52 if (!NT_SUCCESS(Status))
53 {
54 /* failed to create pdo */
55 return Status;
56 }
57
58 /* now allocate device extension */
60 if (!DeviceExtension)
61 {
62 /* no memory */
65 }
66
67 /* store device extension */
68 *((PVOID*)DeviceObject->DeviceExtension) = DeviceExtension;
69
70 /* initialize device extension */
71 DeviceExtension->IsBus = FALSE;
72 DeviceExtension->DeviceObject = DeviceObject;
73 DeviceExtension->DeviceEntry = DeviceEntry;
74 DeviceExtension->BusDeviceExtension = BusDeviceExtension;
75
76 /* not started yet*/
77 DeviceEntry->DeviceState = NotStarted;
78
79 /* get current time */
80 KeQueryTickCount(&DeviceEntry->TimeCreated);
81
82 /* setup flags */
84 DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
85 /* TODO: fire time when expired */
86
87 *OutDeviceObject = DeviceObject;
88
89 return STATUS_SUCCESS;
90}
91
94 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
95 IN PBUS_DEVICE_ENTRY DeviceEntry,
96 IN OUT PBUS_INSTANCE_ENTRY BusInstanceEntry)
97{
100
101 /* initialize reference string */
102 RtlInitUnicodeString(&ReferenceString, DeviceEntry->DeviceName);
103
104 /* register device interface */
105 Status = IoRegisterDeviceInterface(BusDeviceExtension->PhysicalDeviceObject, &BusInstanceEntry->InterfaceGuid, &ReferenceString, &BusInstanceEntry->SymbolicLink);
106
107 /* check for success */
108 if (!NT_SUCCESS(Status))
109 {
110 /* failed */
111 return Status;
112 }
113
114 /* now enable the interface */
115 Status = IoSetDeviceInterfaceState(&BusInstanceEntry->SymbolicLink, TRUE);
116
117 /* check for success */
118 if (!NT_SUCCESS(Status))
119 {
120 /* failed, free memory */
121 FreeItem(BusInstanceEntry->SymbolicLink.Buffer);
122 return Status;
123 }
124
125 DPRINT("Registered DeviceInterface %wZ\n", &BusInstanceEntry->SymbolicLink);
126
127
128 /* done */
129 return Status;
130}
131
132VOID
134 IN PBUS_DEVICE_ENTRY DeviceEntry)
135{
137 PBUS_INSTANCE_ENTRY CurEntry;
138
139 /* remove all entries */
140 Entry = DeviceEntry->DeviceInterfaceList.Flink;
141
142 while(Entry != &DeviceEntry->DeviceInterfaceList)
143 {
144 /* get offset */
146
147 /* sanity check */
148 ASSERT(CurEntry->SymbolicLink.Buffer);
149
150 /* de-register interface */
152
153 /* free symbolic link buffer */
154 FreeItem(CurEntry->SymbolicLink.Buffer);
155
156 /* remove entry from list */
158
159 /* move to next entry */
160 Entry = Entry->Flink;
161
162 /* free entry */
163 FreeItem(CurEntry);
164 }
165}
166
169 IN HANDLE hKey,
172 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
173 IN PBUS_DEVICE_ENTRY DeviceEntry)
174{
177 HANDLE hNewKey;
179 ULONG ResultLength, Index, KeyInfoLength;
180 KEY_FULL_INFORMATION KeyInformation;
182
183 /* initialize key name */
185
186 /* initialize object attributes */
188
189 /* open new key */
190 Status = ZwOpenKey(&hNewKey, GENERIC_READ, &ObjectAttributes);
191
192 /* check for success */
193 if (!NT_SUCCESS(Status))
194 {
195 /* failed to open key */
196
197 return Status;
198 }
199
200 /* query key stats */
201 Status = ZwQueryKey(hNewKey, KeyFullInformation, &KeyInformation, sizeof(KeyInformation), &ResultLength);
202
203 if (!NT_SUCCESS(Status))
204 {
205 /* close key */
206 ZwClose(hNewKey);
207
208 /* done */
209 return Status;
210 }
211
212 /* calculate key info length */
213 KeyInfoLength = KeyInformation.MaxNameLen + sizeof(KEY_BASIC_INFORMATION) + 1 * sizeof(WCHAR);
214
215 /* allocate buffer */
216 KeyInfo = (PKEY_BASIC_INFORMATION)AllocateItem(NonPagedPool, KeyInfoLength);
217 if (!KeyInfo)
218 {
219
220 /* no memory */
221 ZwClose(hNewKey);
222
223 /* done */
225 }
226
227 /* enumerate all keys */
228 for(Index = 0; Index < KeyInformation.SubKeys; Index++)
229 {
230
231 /* query sub key */
232 Status = ZwEnumerateKey(hNewKey, Index, KeyBasicInformation, (PVOID)KeyInfo, KeyInfoLength, &ResultLength);
233
234 /* check for success */
235 if (NT_SUCCESS(Status))
236 {
237 /* perform callback */
238 Status = Callback(hNewKey, BusDeviceExtension, DeviceEntry, KeyInfo->Name, ReferenceString);
239
240 /* should enumeration stop */
241 if (!NT_SUCCESS(Status))
242 break;
243 }
244 }
245
246 /* free info buffer */
247 FreeItem(KeyInfo);
248
249 /* close key */
250 ZwClose(hNewKey);
251
252 /* done */
253 return Status;
254}
255
257NTAPI
260 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
261 IN PBUS_DEVICE_ENTRY DeviceEntry,
262 IN LPWSTR InterfaceString,
264{
265 GUID InterfaceGUID;
268 PBUS_INSTANCE_ENTRY CurEntry;
270
271 /* initialize interface string */
272 RtlInitUnicodeString(&DeviceName, InterfaceString);
273
274 /* first convert device name to guid */
275 RtlGUIDFromString(&DeviceName, &InterfaceGUID);
276
277 /* check if the device is already present */
278 Entry = DeviceEntry->DeviceInterfaceList.Flink;
279 DPRINT("KspCreateDeviceAssociation ReferenceString %S\n", ReferenceString);
280 DPRINT("KspCreateDeviceAssociation InterfaceString %S\n", InterfaceString);
281
282 while(Entry != &DeviceEntry->DeviceInterfaceList)
283 {
284 /* get offset */
286
287 if (IsEqualGUIDAligned(&CurEntry->InterfaceGuid, &InterfaceGUID))
288 {
289 /* entry already exists */
290 return STATUS_SUCCESS;
291 }
292
293 /* move to next entry */
294 Entry = Entry->Flink;
295 }
296
297 /* time to allocate new entry */
299
300 if (!CurEntry)
301 {
302 /* no memory */
304 }
305
306 /* store guid */
307 RtlMoveMemory(&CurEntry->InterfaceGuid, &InterfaceGUID, sizeof(GUID));
308
309 /* now register the association */
310 Status = KspRegisterDeviceAssociation(BusDeviceExtension, DeviceEntry, CurEntry);
311
312 /* check for success */
313 if (NT_SUCCESS(Status))
314 {
315 /* store entry */
316 InsertTailList(&DeviceEntry->DeviceInterfaceList, &CurEntry->Entry);
317 }
318 else
319 {
320 /* failed to associated device */
321 FreeItem(CurEntry);
322 }
323
324 /* done */
325 return Status;
326}
327
329NTAPI
332 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
333 IN PBUS_DEVICE_ENTRY DummyEntry,
334 IN LPWSTR InterfaceId,
335 IN LPWSTR DeviceId)
336{
340 PBUS_DEVICE_ENTRY DeviceEntry = NULL; /* GCC warning */
341 BOOLEAN ItemExists = FALSE;
344 KIRQL OldLevel;
345
346 /* first construct device name & reference guid */
347 Length = wcslen(DeviceId) + wcslen(InterfaceId);
348
349 /* append '&' and null byte */
350 Length += 2;
351
352 /* allocate device name */
354
355 if (!DeviceName)
356 {
357 /* not enough memory */
359 }
360
361 /* construct device name */
362 wcscpy(DeviceName, DeviceId);
363 wcscat(DeviceName, L"&");
364 wcscat(DeviceName, InterfaceId);
365
366 /* scan list and check if it is already present */
367 Entry = BusDeviceExtension->Common.Entry.Flink;
368
369 while(Entry != &BusDeviceExtension->Common.Entry)
370 {
371 /* get real offset */
373
374 /* check if name matches */
375 if (!wcsicmp(DeviceEntry->DeviceName, DeviceName))
376 {
377 /* item already exists */
378 ItemExists = TRUE;
379 break;
380 }
381
382 /* move to next entry */
383 Entry = Entry->Flink;
384 }
385
386 if (!ItemExists)
387 {
388 /* allocate new device entry */
389 DeviceEntry = AllocateItem(NonPagedPool, sizeof(BUS_DEVICE_ENTRY));
390 if (!DeviceEntry)
391 {
392 /* no memory */
395 }
396
397 /* initialize device entry */
399 InitializeListHead(&DeviceEntry->IrpPendingList);
400
401 /* copy device guid */
402 RtlInitUnicodeString(&String, DeviceId);
403 RtlGUIDFromString(&String, &DeviceEntry->DeviceGuid);
404
405 /* copy device names */
406 DeviceEntry->DeviceName = DeviceName;
407 DeviceEntry->Instance = (DeviceName + wcslen(DeviceId) + 1);
408
409 /* copy name */
410 DeviceEntry->BusId = AllocateItem(NonPagedPool, (wcslen(DeviceId) + 1) * sizeof(WCHAR));
411 if (!DeviceEntry->BusId)
412 {
413 /* no memory */
415 FreeItem(DeviceEntry);
417 }
418 wcscpy(DeviceEntry->BusId, DeviceId);
419 }
420
421 /* now enumerate the interfaces */
422 Status = KspEnumerateBusRegistryKeys(hKey, InterfaceId, KspCreateDeviceAssociation, BusDeviceExtension, DeviceEntry);
423
424 /* check if list is empty */
425 if (IsListEmpty(&DeviceEntry->DeviceInterfaceList))
426 {
427 /* invalid device settings */
428 FreeItem(DeviceEntry->BusId);
429 FreeItem(DeviceEntry->DeviceName);
430 FreeItem(DeviceEntry);
431
432 ASSERT(ItemExists == FALSE);
433
435 }
436
437 /* check if enumeration failed */
438 if (!NT_SUCCESS(Status))
439 {
440 /* failed */
441 KspRemoveDeviceAssociations(DeviceEntry);
442 FreeItem(DeviceEntry->BusId);
443 FreeItem(DeviceEntry->DeviceName);
444 FreeItem(DeviceEntry);
445
446 ASSERT(ItemExists == FALSE);
447
448 /* done */
449 return Status;
450 }
451
452 if (!ItemExists)
453 {
454 /* acquire lock */
455 KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
456
457 /* successfully initialized entry */
458 InsertTailList(&BusDeviceExtension->Common.Entry, &DeviceEntry->Entry);
459
460 /* release lock */
461 KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
462 }
463
464 /* done */
465 return Status;
466}
467
469NTAPI
472 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
473 IN PBUS_DEVICE_ENTRY DummyEntry,
474 IN LPWSTR DeviceCategory,
476{
477 return KspEnumerateBusRegistryKeys(hKey, DeviceCategory, KspCreateDeviceReference, BusDeviceExtension, DummyEntry);
478}
479
480
483 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
485{
487
488 /* initialize object attributes */
490
491 return ZwCreateKey(hKey, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
492}
493
496 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension)
497{
498 HANDLE hKey;
500
501 /* first open key */
502 Status = KspOpenBusRegistryKey(BusDeviceExtension, &hKey);
503
504 /* check for success */
505 if (!NT_SUCCESS(Status))
506 {
507 /* no success */
508
509 return Status;
510 }
511
512 /* TODO clear reference marks */
513
514 /* construct device entries */
516
517 /* TODO: delete unreferenced devices */
518
519 /* close handle */
520 ZwClose(hKey);
521
522 /* done */
523 return Status;
524}
525
526
528NTAPI
532{
533 LPWSTR Name;
536
537 /* sanity checks */
538 ASSERT(BusDeviceExtension);
539 ASSERT(BusDeviceExtension->BusIdentifier);
540
541 /* calculate length */
542 Length = wcslen(BusDeviceExtension->BusIdentifier) + 1;
543
544 /* allocate buffer */
545 Name = AllocateItem(PagedPool, Length * sizeof(WCHAR));
546
547 if (!Name)
548 {
549 /* failed to allocate buffer */
551 }
552
553 /* copy buffer */
554 wcscpy(Name, BusDeviceExtension->BusIdentifier);
555
556 /* store result */
557 *String = Name;
558
559 /* done */
560 return STATUS_SUCCESS;
561}
562
563VOID
564NTAPI
567{
569
570 /* reference count */
571 InterlockedIncrement((PLONG)&ChildDeviceExtension->DeviceReferenceCount);
572}
573
574VOID
575NTAPI
578{
580
581 /* reference count */
582 InterlockedDecrement((PLONG)&ChildDeviceExtension->DeviceReferenceCount);
583}
584
585VOID
586NTAPI
589{
591
592 /* reference count */
593 InterlockedIncrement((PLONG)&ChildDeviceExtension->DeviceObjectReferenceCount);
594}
595
596VOID
597NTAPI
600{
602
603 /* reference count */
604 InterlockedDecrement((PLONG)&ChildDeviceExtension->DeviceObjectReferenceCount);
605}
606
609 IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
610 IN PIRP Irp)
611{
612 PBUS_INTERFACE_SWENUM Interface;
613 PIO_STACK_LOCATION IoStack;
614
615 /* get current irp stack location */
617
618 /* sanity checks */
619 ASSERT(IoStack->Parameters.QueryInterface.Size == sizeof(BUS_INTERFACE_SWENUM));
620 ASSERT(IoStack->Parameters.QueryInterface.Interface);
621
622 /* fill in interface */
623 Interface = (PBUS_INTERFACE_SWENUM)IoStack->Parameters.QueryInterface.Interface;
624 Interface->Interface.Size = sizeof(BUS_INTERFACE_SWENUM);
625 Interface->Interface.Version = BUS_INTERFACE_SWENUM_VERSION;
626 Interface->Interface.Context = ChildDeviceExtension;
627 Interface->Interface.InterfaceReference = KspBusDeviceReference;
628 Interface->Interface.InterfaceDereference = KspBusDeviceDereference;
629 Interface->ReferenceDeviceObject = KspBusReferenceDeviceObject;
630 Interface->DereferenceDeviceObject = KspBusDereferenceDeviceObject;
631 Interface->QueryReferenceString = KspBusQueryReferenceString;
632
633 return STATUS_SUCCESS;
634}
635
638 PBUS_DEVICE_ENTRY DeviceEntry,
640{
642 PBUS_INSTANCE_ENTRY InstanceEntry;
644
645 /* enable now all interfaces */
646 Entry = DeviceEntry->DeviceInterfaceList.Flink;
647
648 while(Entry != &DeviceEntry->DeviceInterfaceList)
649 {
650 /* get bus instance entry */
652 DPRINT("Enabling %u %wZ Irql %u\n", bEnable, &InstanceEntry->SymbolicLink, KeGetCurrentIrql());
653
654 /* set interface state */
656
657 if (!NT_SUCCESS(Status))
658 {
659 /* failed to set interface */
660 break;
661 }
662
663 /* move to next entry */
664 Entry = Entry->Flink;
665 }
666
667 /* done */
668 return Status;
669}
670
673 PIRP Irp,
674 PBUS_DEVICE_ENTRY DeviceEntry)
675{
678 PIO_STACK_LOCATION IoStack;
679
680 /* get stack location */
682
683 /* sanity checks */
684 ASSERT(DeviceEntry->PDODeviceName);
685 ASSERT(DeviceEntry->Instance);
686 ASSERT(IoStack->FileObject);
687 ASSERT(IoStack->FileObject->FileName.Buffer);
688
689 /* calculate length */
690 Length = wcslen(DeviceEntry->PDODeviceName);
691 Length += wcslen(DeviceEntry->Instance);
692
693 /* zero byte and '\\' */
694 Length += 2;
695
696 /* allocate buffer */
698 if (!Buffer)
699 {
700 /* no resources */
702 }
703
704 /* construct buffer */
705 swprintf(Buffer, L"%s\\%s", DeviceEntry->PDODeviceName, DeviceEntry->Instance);
706
707 /* free old buffer*/
708 ExFreePoolWithTag(IoStack->FileObject->FileName.Buffer, 'mNoI');
709
710 /* store new file name */
711 RtlInitUnicodeString(&IoStack->FileObject->FileName, Buffer);
712
713 /* done */
714 return STATUS_REPARSE;
715}
716
717VOID
719 IN PBUS_DEVICE_ENTRY DeviceEntry,
720 IN OUT NTSTATUS ResultCode)
721{
723 PIRP Irp;
725
726 /* go through list */
727 while(!IsListEmpty(&DeviceEntry->IrpPendingList))
728 {
729 /* get first entry */
730 Entry = RemoveHeadList(&DeviceEntry->IrpPendingList);
731
732 /* get irp */
733 Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
734
735 if (ResultCode == STATUS_REPARSE)
736 {
737 /* construct reparse information */
738 Status = KspDoReparseForIrp(Irp, DeviceEntry);
739 }
740 else
741 {
742 /* use default code */
743 Status = ResultCode;
744 }
745
746 /* store result code */
747 Irp->IoStatus.Status = Status;
748
749 DPRINT("Completing IRP %p Status %x\n", Irp, Status);
750
751 /* complete the request */
753 }
754
755}
756
757
758
762 IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
763 IN PIRP Irp)
764{
765 WCHAR PDOName[256];
768 LPWSTR Name;
769 ULONG NameLength;
770 PBUS_DEVICE_ENTRY DeviceEntry;
771
772 /* FIXME handle pending remove */
773
774 /* get full device name */
776
777 if (!NT_SUCCESS(Status))
778 {
779 /* failed to get device name */
780 return Status;
781 }
782
783 /* allocate device name buffer */
784 NameLength = ResultLength + sizeof(UNICODE_NULL);
785 Name = AllocateItem(NonPagedPool, NameLength);
786 if (!Name)
787 {
788 /* no memory */
790 }
791
792 /* copy name */
793 NT_VERIFY(NT_SUCCESS(RtlStringCbCopyW(Name, NameLength, PDOName)));
794
795 /* TODO: time stamp creation time */
796
797 /* get device entry */
798 DeviceEntry = (PBUS_DEVICE_ENTRY)ChildDeviceExtension->DeviceEntry;
799
800 /* sanity check */
801 ASSERT(DeviceEntry);
802
803 /* store device name */
804 DeviceEntry->PDODeviceName = Name;
805
806 /* mark device as started */
807 DeviceEntry->DeviceState = Started;
808
809 /* reference start time */
810 KeQueryTickCount(&DeviceEntry->TimeCreated);
811
812 DPRINT1("KspStartBusDevice Name %S DeviceName %S Instance %S Started\n", Name, DeviceEntry->DeviceName, DeviceEntry->Instance);
813
814 /* enable device classes */
815 //KspEnableBusDeviceInterface(DeviceEntry, TRUE);
816
817 /* done */
818 return STATUS_SUCCESS;
819}
820
823 IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
824 IN PIRP Irp)
825{
827 PIO_STACK_LOCATION IoStack;
828
829 /* get stack location */
831
832 /* get capabilities */
833 Capabilities = IoStack->Parameters.DeviceCapabilities.Capabilities;
834
836
837 /* setup capabilities */
838 Capabilities->UniqueID = TRUE;
839 Capabilities->SilentInstall = TRUE;
840 Capabilities->SurpriseRemovalOK = TRUE;
841 Capabilities->Address = 0;
842 Capabilities->UINumber = 0;
843 Capabilities->SystemWake = PowerSystemWorking; /* FIXME common device extension */
844 Capabilities->DeviceWake = PowerDeviceD0;
845
846 /* done */
847 return STATUS_SUCCESS;
848}
849
852 IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
853 IN PIRP Irp)
854{
856
857 /* allocate bus information */
859
860 if (!BusInformation)
861 {
862 /* no memory */
864 }
865
866 /* return info */
867 BusInformation->BusNumber = 0;
868 BusInformation->LegacyBusType = InterfaceTypeUndefined;
870
871 /* store result */
872 Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
873
874 /* done */
875 return STATUS_SUCCESS;
876}
877
880 IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
881 IN PIRP Irp)
882{
883 /* set device flags */
885
886 /* done */
887 return STATUS_SUCCESS;
888}
889
892 IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
893 IN PIRP Irp)
894{
895 PIO_STACK_LOCATION IoStack;
896 PBUS_DEVICE_ENTRY DeviceEntry;
897 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
898 LPWSTR Name;
900
901 /* get current irp stack location */
903
904 if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
905 {
906 /* get device entry */
907 DeviceEntry = (PBUS_DEVICE_ENTRY) ChildDeviceExtension->DeviceEntry;
908
909 /* sanity check */
910 ASSERT(DeviceEntry);
911 ASSERT(DeviceEntry->Instance);
912
913 /* calculate length */
914 Length = wcslen(DeviceEntry->Instance) + 2;
915
916 /* allocate buffer */
917 Name = AllocateItem(PagedPool, Length * sizeof(WCHAR));
918
919 if (!Name)
920 {
921 /* failed to allocate buffer */
923 }
924
925 /* copy buffer */
926 wcscpy(Name, DeviceEntry->Instance);
927
928 /* store result */
929 Irp->IoStatus.Information = (ULONG_PTR)Name;
930
931 /* done */
932 return STATUS_SUCCESS;
933 }
934 else if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID ||
935 IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
936 {
937 /* get device entry */
938 DeviceEntry = (PBUS_DEVICE_ENTRY) ChildDeviceExtension->DeviceEntry;
939
940 /* get bus device extension */
941 BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION) ChildDeviceExtension->BusDeviceExtension;
942
943 /* sanity check */
944 ASSERT(DeviceEntry);
945 ASSERT(DeviceEntry->BusId);
946 ASSERT(BusDeviceExtension);
947 ASSERT(BusDeviceExtension->BusIdentifier);
948
949 /* calculate length */
950 Length = wcslen(BusDeviceExtension->BusIdentifier);
951 Length += wcslen(DeviceEntry->BusId);
952
953 /* extra length for '\\' and 2 zero bytes */
954 Length += 4;
955
956 /* allocate buffer */
957 Name = AllocateItem(PagedPool, Length * sizeof(WCHAR));
958 if (!Name)
959 {
960 /* failed to allocate buffer */
962 }
963
964 /* construct id */
965 wcscpy(Name, BusDeviceExtension->BusIdentifier);
966 wcscat(Name, L"\\");
967 wcscat(Name, DeviceEntry->BusId);
968 //swprintf(Name, L"%s\\%s", BusDeviceExtension->BusIdentifier, DeviceEntry->BusId);
969
970 /* store result */
971 Irp->IoStatus.Information = (ULONG_PTR)Name;
972
973 /* done */
974 return STATUS_SUCCESS;
975 }
976 else
977 {
978 /* other ids are not supported */
979 //DPRINT1("Not Supported ID Type %x\n", IoStack->Parameters.QueryId.IdType);
980 return Irp->IoStatus.Status;
981 }
982}
983
986 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
987 IN PSWENUM_INSTALL_INTERFACE InstallInterface)
988{
990 UNICODE_STRING DeviceString, InterfaceString, ReferenceString;
991 HANDLE hKey, hDeviceKey, hInterfaceKey, hReferenceKey;
994
995 /* sanity check */
996 ASSERT(InstallInterface);
997
998 /* calculate length */
999 Length = wcslen(InstallInterface->ReferenceString);
1000
1001 /* check for invalid characters */
1002 for(Index = 0; Index < Length; Index++)
1003 {
1004 if (InstallInterface->ReferenceString[Index] <= L' ' ||
1005 InstallInterface->ReferenceString[Index] > L'~' ||
1006 InstallInterface->ReferenceString[Index] == L',' ||
1007 InstallInterface->ReferenceString[Index] == L'\\' ||
1008 InstallInterface->ReferenceString[Index] == L'/')
1009 {
1010 /* invalid character */
1012 }
1013 }
1014
1015 /* open bus key */
1016 Status = KspOpenBusRegistryKey(BusDeviceExtension, &hKey);
1017 if (NT_SUCCESS(Status))
1018 {
1019 /* convert device guid to string */
1020 Status = RtlStringFromGUID(&InstallInterface->DeviceId, &DeviceString);
1021 if (NT_SUCCESS(Status))
1022 {
1023 /* initialize object attributes */
1025
1026 /* construct device key */
1027 Status = ZwCreateKey(&hDeviceKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
1028 if (NT_SUCCESS(Status))
1029 {
1030 /* convert interface guid to string */
1031 Status = RtlStringFromGUID(&InstallInterface->InterfaceId, &InterfaceString);
1032 if (NT_SUCCESS(Status))
1033 {
1034 /* initialize object attributes */
1036
1037 /* construct device key */
1038 Status = ZwCreateKey(&hInterfaceKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
1039 if (NT_SUCCESS(Status))
1040 {
1041 /* initialize reference string */
1042 RtlInitUnicodeString(&ReferenceString, InstallInterface->ReferenceString);
1043
1044 /* initialize object attributes */
1046
1047 /* construct device key */
1048 Status = ZwCreateKey(&hReferenceKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
1049 if (NT_SUCCESS(Status))
1050 {
1051 /* close key */
1052 ZwClose(hReferenceKey);
1053 }
1054 }
1055 /* free interface string */
1056 RtlFreeUnicodeString(&InterfaceString);
1057
1058 /* close reference key */
1059 ZwClose(hInterfaceKey);
1060 }
1061 /* close device key */
1062 ZwClose(hDeviceKey);
1063 }
1064 /* free device string */
1065 RtlFreeUnicodeString(&DeviceString);
1066 }
1067 /* close bus key */
1068 ZwClose(hKey);
1069 }
1070
1071 /* done */
1072 return Status;
1073 }
1074
1075VOID
1076NTAPI
1078 IN PVOID Ctx)
1079{
1080 PIO_STACK_LOCATION IoStack;
1083 PBUS_DEVICE_ENTRY DeviceEntry;
1084 PSWENUM_INSTALL_INTERFACE InstallInterface;
1085 KIRQL OldLevel;
1087
1088 /* get current irp stack location */
1089 IoStack = IoGetCurrentIrpStackLocation(Context->Irp);
1090
1091 /* get install request */
1092 InstallInterface = (PSWENUM_INSTALL_INTERFACE)Context->Irp->AssociatedIrp.SystemBuffer;
1093
1094 /* sanity check */
1095 ASSERT(InstallInterface);
1096 ASSERT(Context->BusDeviceExtension);
1097
1098 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SWENUM_INSTALL_INTERFACE))
1099 {
1100 /* buffer too small */
1102
1103 /* signal completion */
1104 KeSetEvent(&Context->Event, 0, FALSE);
1105
1106 /* done */
1107 return;
1108 }
1109
1110 /* FIXME locks */
1111
1112 /* now install the interface */
1113 Status = KspInstallInterface(Context->BusDeviceExtension, InstallInterface);
1114 if (!NT_SUCCESS(Status))
1115 {
1116 /* failed to install interface */
1117 Context->Status = Status;
1118
1119 /* signal completion */
1120 KeSetEvent(&Context->Event, 0, FALSE);
1121
1122 /* done */
1123 return;
1124 }
1125
1126 /* now scan the bus */
1127 Status = KspScanBus(Context->BusDeviceExtension);
1128 // FIXME: We may need to check for success here, and properly fail...
1130
1131 /* acquire device entry lock */
1132 KeAcquireSpinLock(&Context->BusDeviceExtension->Lock, &OldLevel);
1133
1134 /* now iterate all device entries */
1135 ASSERT(!IsListEmpty(&Context->BusDeviceExtension->Common.Entry));
1136 Entry = Context->BusDeviceExtension->Common.Entry.Flink;
1137 while(Entry != &Context->BusDeviceExtension->Common.Entry)
1138 {
1139 /* get device entry */
1141 if (IsEqualGUIDAligned(&DeviceEntry->DeviceGuid, &InstallInterface->DeviceId))
1142 {
1143 if (!DeviceEntry->PDO)
1144 {
1145 /* release device entry lock */
1146 KeReleaseSpinLock(&Context->BusDeviceExtension->Lock, OldLevel);
1147
1148 /* create pdo */
1149 Status = KspCreatePDO(Context->BusDeviceExtension, DeviceEntry, &DeviceEntry->PDO);
1150
1151 /* acquire device entry lock */
1152 KeAcquireSpinLock(&Context->BusDeviceExtension->Lock, &OldLevel);
1153
1154 /* done */
1155 break;
1156 }
1157 }
1158
1159 /* move to next entry */
1160 Entry = Entry->Flink;
1161 }
1162
1163 /* release device entry lock */
1164 KeReleaseSpinLock(&Context->BusDeviceExtension->Lock, OldLevel);
1165
1166 /* signal that bus driver relations has changed */
1167 IoInvalidateDeviceRelations(Context->BusDeviceExtension->PhysicalDeviceObject, BusRelations);
1168
1169 /* update status */
1170 Context->Status = Status;
1171
1172 /* signal completion */
1173 KeSetEvent(&Context->Event, 0, FALSE);
1174}
1175
1176
1177VOID
1178NTAPI
1181{
1182 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
1183 PBUS_DEVICE_ENTRY DeviceEntry;
1185 LARGE_INTEGER Time, Diff;
1186 BOOLEAN DoInvalidate = FALSE;
1187 KIRQL OldLevel;
1188
1189 /* get device extension */
1190 BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)Parameter;
1191
1192 /* acquire lock */
1193 KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
1194
1195 /* get current time */
1197
1198 /* enumerate all device entries */
1199 Entry = BusDeviceExtension->Common.Entry.Flink;
1200 while(Entry != &BusDeviceExtension->Common.Entry)
1201 {
1202 /* get offset to device entry */
1204
1205 /* sanity check */
1206 ASSERT(DeviceEntry);
1207
1208 //DPRINT1("DeviceEntry %p PDO %p State %x\n", DeviceEntry, DeviceEntry->PDO, DeviceEntry->DeviceState);
1209
1210 if (DeviceEntry->PDO)
1211 {
1212 if (DeviceEntry->DeviceState == NotStarted)
1213 {
1214 Diff.QuadPart = (Time.QuadPart - DeviceEntry->TimeCreated.QuadPart) * KeQueryTimeIncrement();
1215
1216 /* wait for 15 sec */
1217 if (Diff.QuadPart > Int32x32To64(15000, 10000))
1218 {
1219 /* release spin lock */
1220 KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
1221
1222 DPRINT1("DeviceID %S Instance %S TimeCreated %I64u Now %I64u Diff %I64u hung\n",
1223 DeviceEntry->DeviceName,
1224 DeviceEntry->Instance,
1225 DeviceEntry->TimeCreated.QuadPart * KeQueryTimeIncrement(),
1227 Diff.QuadPart);
1228
1229 /* deactivate interfaces */
1230 //KspEnableBusDeviceInterface(DeviceEntry, FALSE);
1231
1232 /* re-acquire lock */
1233 KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
1234
1235 /* pending remove device object */
1236 DeviceEntry->DeviceState = StopPending;
1237
1238 /* perform invalidation */
1239 DoInvalidate = TRUE;
1240 }
1241 }
1242 else if (DeviceEntry->DeviceState == Started)
1243 {
1244 /* release spin lock */
1245 KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
1246
1247 /* found pending irps */
1249
1250 /* re-acquire lock */
1251 KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
1252 }
1253 }
1254
1255
1256 /* move to next */
1257 Entry = Entry->Flink;
1258 }
1259
1260 /* release lock */
1261 KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
1262
1263 if (DoInvalidate)
1264 {
1265 /* invalidate device relations */
1267 }
1268
1269 Time.QuadPart = Int32x32To64(5000, -10000);
1270 KeSetTimer(&BusDeviceExtension->Timer, Time, &BusDeviceExtension->Dpc);
1271}
1272
1273VOID
1274NTAPI
1276 IN PKDPC Dpc,
1280{
1281 /* get device extension */
1283
1284 /* queue the item */
1285 ExQueueWorkItem(&BusDeviceExtension->WorkItem, DelayedWorkQueue);
1286}
1287
1288VOID
1289NTAPI
1291 PVOID Ctx)
1292{
1294
1295 /* TODO
1296 * get SWENUM_INSTALL_INTERFACE struct
1297 * open device key and delete the keys
1298 */
1299
1301
1302 /* set status */
1304
1305
1306 /* signal completion */
1308}
1309
1312 IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
1313 IN PIRP Irp)
1314{
1315 PDEVICE_RELATIONS DeviceRelations;
1317 PBUS_DEVICE_ENTRY DeviceEntry;
1318 ULONG Count = 0, Length;
1319 KIRQL OldLevel;
1320
1321 /* acquire lock */
1322 KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
1323
1324 /* first scan all device entries */
1325 Entry = BusDeviceExtension->Common.Entry.Flink;
1326
1327 while(Entry != &BusDeviceExtension->Common.Entry)
1328 {
1329 /* get offset to device entry */
1331
1332 /* is there a pdo yet */
1333 if (DeviceEntry->PDO && (DeviceEntry->DeviceState == NotStarted || DeviceEntry->DeviceState == Started))
1334 {
1335 /* increment count */
1336 Count++;
1337 }
1338
1339 /* move to next entry */
1340 Entry = Entry->Flink;
1341 }
1342
1343 /* calculate length */
1344 Length = sizeof(DEVICE_RELATIONS) + (Count > 1 ? sizeof(PDEVICE_OBJECT) * (Count-1) : 0);
1345
1346 /* allocate device relations */
1348
1349 if (!DeviceRelations)
1350 {
1351 /* not enough memory */
1352 KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
1354 }
1355
1356 /* rescan device entries */
1357 Entry = BusDeviceExtension->Common.Entry.Flink;
1358
1359 while(Entry != &BusDeviceExtension->Common.Entry)
1360 {
1361 /* get offset to device entry */
1363
1364 /* is there a pdo yet */
1365 if (DeviceEntry->PDO && (DeviceEntry->DeviceState == NotStarted || DeviceEntry->DeviceState == Started))
1366 {
1367 /* store pdo */
1368 DeviceRelations->Objects[DeviceRelations->Count] = DeviceEntry->PDO;
1369
1370 /* reference device object */
1371 ObReferenceObject(DeviceEntry->PDO);
1372
1373 /* increment pdo count */
1374 DeviceRelations->Count++;
1375 }
1376
1377 /* move to next entry */
1378 Entry = Entry->Flink;
1379 }
1380
1381 /* release lock */
1382 KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
1383
1384 /* FIXME handle existing device relations */
1385 ASSERT(Irp->IoStatus.Information == 0);
1386
1387 /* store device relations */
1388 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
1389
1390 /* done */
1391 return STATUS_SUCCESS;
1392}
1393
1394//------------------------------------------------------------------------------------
1395
1396/*
1397 @implemented
1398*/
1399
1402NTAPI
1404 IN PIRP Irp)
1405{
1406 PDEV_EXTENSION DeviceExtension;
1407 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
1408 PIO_STACK_LOCATION IoStack;
1409 SIZE_T Length;
1411 LPWSTR Buffer;
1412
1413 DPRINT("KsGetBusEnumIdentifier\n");
1414
1415 /* get stack location */
1417
1418 /* sanity checks */
1419 ASSERT(IoStack->DeviceObject);
1421
1422 /* get device extension */
1423 DeviceExtension = (PDEV_EXTENSION)IoStack->DeviceObject->DeviceExtension;
1424
1425 /* get bus device extension */
1426 BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
1427
1428 /* sanity checks */
1429 ASSERT(BusDeviceExtension);
1430 ASSERT(BusDeviceExtension->Common.IsBus);
1431
1432 if (!BusDeviceExtension)
1433 {
1434 /* invalid parameter */
1436 }
1437
1438 /* get length */
1439 Length = (wcslen(BusDeviceExtension->BusIdentifier)+1) * sizeof(WCHAR);
1440
1441 /* is there an output buffer provided */
1442 if (IoStack->Parameters.DeviceIoControl.InputBufferLength)
1443 {
1444 if (Length > IoStack->Parameters.DeviceIoControl.InputBufferLength)
1445 {
1446 /* buffer is too small */
1448 }
1449
1450 /* now allocate buffer */
1452 if (!Buffer)
1453 {
1454 /* no memory */
1456 }
1457 else
1458 {
1459 /* copy bus identifier */
1460 wcscpy(Buffer, BusDeviceExtension->BusIdentifier);
1461
1462 /* store buffer */
1463 Irp->AssociatedIrp.SystemBuffer = Buffer;
1464
1465 /* set flag that buffer gets copied back */
1467
1468 /* done */
1470 }
1471 }
1472 else
1473 {
1474 /* no buffer provided */
1476 }
1477
1478 /* done */
1479 Irp->IoStatus.Status = Status;
1480 return Status;
1481}
1482
1483/*
1484 @implemented
1485*/
1488NTAPI
1492{
1493 PDEV_EXTENSION DeviceExtension;
1494
1495 DPRINT("KsGetBusEnumParentFDOFromChildPDO\n");
1496
1497 /* get device extension */
1498 DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
1499
1500 /* check if this is child pdo */
1501 if (DeviceExtension->Ext->IsBus == FALSE)
1502 {
1503 /* return bus device object */
1504 *FunctionalDeviceObject = DeviceExtension->Ext->BusDeviceExtension->BusDeviceObject;
1505
1506 /* done */
1507 return STATUS_SUCCESS;
1508 }
1509
1510 /* invalid parameter */
1512}
1513
1514
1515/*
1516 @implemented
1517*/
1520NTAPI
1522 IN PWCHAR BusIdentifier,
1523 IN PDEVICE_OBJECT BusDeviceObject,
1525 IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL,
1527 IN PWCHAR ServiceRelativePath OPTIONAL)
1528{
1529 SIZE_T Length;
1531 UNICODE_STRING ServiceKeyPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
1532 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
1533 PDEV_EXTENSION DeviceExtension;
1534 PBUS_DEVICE_ENTRY DeviceEntry;
1536 KIRQL OldLevel;
1537
1538 DPRINT1("KsCreateBusEnumObject %S BusDeviceObject %p\n", ServiceRelativePath, BusDeviceObject);
1539
1540 /* calculate sizeof bus enum device extension */
1541 Length = wcslen(BusIdentifier) * sizeof(WCHAR);
1543
1544 BusDeviceExtension = AllocateItem(NonPagedPool, Length);
1545 if (!BusDeviceExtension)
1546 {
1547 /* not enough memory */
1548
1550 }
1551
1552 /* get device extension */
1553 DeviceExtension = (PDEV_EXTENSION)BusDeviceObject->DeviceExtension;
1554
1555 /* store bus device extension */
1556 DeviceExtension->Ext = (PCOMMON_DEVICE_EXTENSION)BusDeviceExtension;
1557
1558 DPRINT("DeviceExtension %p BusDeviceExtension %p\n", DeviceExtension, DeviceExtension->Ext);
1559
1560
1561 /* zero device extension */
1562 RtlZeroMemory(BusDeviceExtension, sizeof(BUS_ENUM_DEVICE_EXTENSION));
1563
1564 /* initialize bus device extension */
1565 wcscpy(BusDeviceExtension->BusIdentifier, BusIdentifier);
1566
1567 /* allocate service path string */
1568 Length = ServiceKeyPath.MaximumLength;
1569 Length += BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName.MaximumLength;
1570
1571 if (ServiceRelativePath)
1572 {
1573 /* relative path for devices */
1574 Length += (wcslen(ServiceRelativePath) + 2) * sizeof(WCHAR);
1575 }
1576
1577 BusDeviceExtension->ServicePath.Length = 0;
1578 BusDeviceExtension->ServicePath.MaximumLength = (USHORT)Length;
1579 BusDeviceExtension->ServicePath.Buffer = AllocateItem(NonPagedPool, Length);
1580
1581 if (!BusDeviceExtension->ServicePath.Buffer)
1582 {
1583 /* not enough memory */
1584 FreeItem(BusDeviceExtension);
1585
1587 }
1588
1589 RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &ServiceKeyPath);
1590 RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName);
1591
1592 if (ServiceRelativePath)
1593 {
1594 RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, L"\\");
1595 RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, ServiceRelativePath);
1596 }
1597
1598 if (InterfaceGuid)
1599 {
1600 /* register an device interface */
1602
1603 /* check for success */
1604 if (!NT_SUCCESS(Status))
1605 {
1606 DPRINT1("IoRegisterDeviceInterface failed Status %lx\n", Status);
1607 FreeItem(BusDeviceExtension->ServicePath.Buffer);
1608 FreeItem(BusDeviceExtension);
1609 return Status;
1610 }
1611
1612 /* now enable device interface */
1614
1615 if (!NT_SUCCESS(Status))
1616 {
1617 DPRINT1("IoSetDeviceInterfaceState failed Status %lx\n", Status);
1618 FreeItem(BusDeviceExtension->ServicePath.Buffer);
1619 FreeItem(BusDeviceExtension);
1620 return Status;
1621 }
1622 }
1623
1624 /* initialize common device extension */
1625 BusDeviceExtension->Common.BusDeviceExtension = NULL;
1626 BusDeviceExtension->Common.DeviceObjectReferenceCount = 1;
1627 BusDeviceExtension->Common.DeviceReferenceCount = 1;
1628 BusDeviceExtension->Common.IsBus = TRUE;
1629 InitializeListHead(&BusDeviceExtension->Common.Entry);
1630
1631 /* store device objects */
1632 BusDeviceExtension->BusDeviceObject = BusDeviceObject;
1633 BusDeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
1634
1635 /* initialize lock */
1636 KeInitializeSpinLock(&BusDeviceExtension->Lock);
1637
1638 /* initialize timer */
1639 KeInitializeTimer(&BusDeviceExtension->Timer);
1640
1641 /* initialize dpc */
1642 KeInitializeDpc(&BusDeviceExtension->Dpc, KspBusDpcRoutine, (PVOID)BusDeviceExtension);
1643
1644 /* initialize event */
1645 KeInitializeEvent(&BusDeviceExtension->Event, SynchronizationEvent, FALSE);
1646
1647 /* initialize work item */
1648 ExInitializeWorkItem(&BusDeviceExtension->WorkItem, KspBusWorkerRoutine, (PVOID)BusDeviceExtension);
1649
1650 if (!PnpDeviceObject)
1651 {
1652 /* attach device */
1653 BusDeviceExtension->PnpDeviceObject = IoAttachDeviceToDeviceStack(BusDeviceObject, PhysicalDeviceObject);
1654
1655 if (!BusDeviceExtension->PnpDeviceObject)
1656 {
1657 /* failed to attach device */
1658 DPRINT1("IoAttachDeviceToDeviceStack failed with %x\n", Status);
1659 if (BusDeviceExtension->DeviceInterfaceLink.Buffer)
1660 {
1662 RtlFreeUnicodeString(&BusDeviceExtension->DeviceInterfaceLink);
1663 }
1664
1665 /* free device extension */
1666 FreeItem(BusDeviceExtension->ServicePath.Buffer);
1667 FreeItem(BusDeviceExtension);
1668
1669 return STATUS_DEVICE_REMOVED;
1670 }
1671
1672 /* mark device as attached */
1673 BusDeviceExtension->DeviceAttached = TRUE;
1674 }
1675 else
1676 {
1677 /* directly attach */
1678 BusDeviceExtension->PnpDeviceObject = PnpDeviceObject;
1679 }
1680
1681 /* now scan the bus */
1682 Status = KspScanBus(BusDeviceExtension);
1683
1684 /* check for success */
1685 if (!NT_SUCCESS(Status))
1686 {
1687 /* failed to scan bus */
1688 if (BusDeviceExtension->DeviceInterfaceLink.Buffer)
1689 {
1691 RtlFreeUnicodeString(&BusDeviceExtension->DeviceInterfaceLink);
1692 }
1693
1694 if (BusDeviceExtension->DeviceAttached)
1695 {
1696 /* detach device */
1697 IoDetachDevice(BusDeviceExtension->PnpDeviceObject);
1698 }
1699
1700 /* free device extension */
1701 FreeItem(BusDeviceExtension->ServicePath.Buffer);
1702 FreeItem(BusDeviceExtension);
1703
1704 return Status;
1705 }
1706
1707 /* acquire device entry lock */
1708 KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
1709
1710 /* now iterate all device entries */
1711 Entry = BusDeviceExtension->Common.Entry.Flink;
1712 while(Entry != &BusDeviceExtension->Common.Entry)
1713 {
1714 /* get device entry */
1716 if (!DeviceEntry->PDO)
1717 {
1718 /* release device entry lock */
1719 KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
1720
1721 /* create pdo */
1722 Status = KspCreatePDO(BusDeviceExtension, DeviceEntry, &DeviceEntry->PDO);
1723
1724 /* acquire device entry lock */
1725 KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
1726
1727 /* done */
1728 break;
1729 }
1730 /* move to next entry */
1731 Entry = Entry->Flink;
1732 }
1733
1734 /* release device entry lock */
1735 KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
1736
1737
1738 /* invalidate device relations */
1740 DPRINT("KsCreateBusEnumObject Status %x\n", Status);
1741 /* done */
1742 return Status;
1743}
1744
1745/*
1746 @implemented
1747*/
1750NTAPI
1753 IN PDEVICE_OBJECT *PnpDeviceObject)
1754{
1755 PDEV_EXTENSION DeviceExtension;
1756 PCOMMON_DEVICE_EXTENSION CommonDeviceExtension;
1757 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
1758
1759 DPRINT("KsGetBusEnumPnpDeviceObject\n");
1760
1761 if (!DeviceObject->DeviceExtension)
1762 {
1763 /* invalid parameter */
1765 }
1766
1767 /* get device extension */
1768 DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
1769
1770 /* get common device extension */
1771 CommonDeviceExtension = DeviceExtension->Ext;
1772
1773 if (!CommonDeviceExtension)
1774 {
1775 /* invalid parameter */
1777 }
1778
1779 if (!CommonDeviceExtension->IsBus)
1780 {
1781 /* getting pnp device object is only supported for software bus device object */
1783 }
1784
1785 /* sanity checks */
1786 ASSERT(CommonDeviceExtension);
1787 ASSERT(CommonDeviceExtension->IsBus);
1788
1789 /* cast to bus device extension */
1790 BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)CommonDeviceExtension;
1791
1792 /* store result */
1793 *PnpDeviceObject = BusDeviceExtension->PnpDeviceObject;
1794
1795 /* done */
1796 return STATUS_SUCCESS;
1797}
1798
1799/*
1800 @implemented
1801*/
1804NTAPI
1806 PIRP Irp)
1807{
1810 LUID luid;
1811 PIO_STACK_LOCATION IoStack;
1812 PDEV_EXTENSION DeviceExtension;
1813 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
1814
1815 DPRINT("KsInstallBusEnumInterface\n");
1816
1817 /* get current irp stack location */
1819
1820 /* get previous mode */
1822
1823 /* convert to luid */
1825
1826 /* perform access check */
1827 if (!SeSinglePrivilegeCheck(luid, Mode))
1828 {
1829 /* FIXME insufficient privileges */
1830 //return STATUS_PRIVILEGE_NOT_HELD;
1831 }
1832
1833 /* get device extension */
1834 DeviceExtension = (PDEV_EXTENSION)IoStack->DeviceObject->DeviceExtension;
1835
1836 /* get bus device extension */
1837 BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
1838
1839
1840 /* initialize context */
1841 Context.Irp = Irp;
1843 Context.BusDeviceExtension = BusDeviceExtension;
1845
1846 /* queue the work item */
1848 /* wait for completion */
1850
1851 /* store result */
1852 Irp->IoStatus.Status = Context.Status;
1853
1854 /* done */
1855 return Context.Status;
1856}
1857
1858/*
1859 @implemented
1860*/
1863NTAPI
1866 OUT PBOOLEAN ChildDevice)
1867{
1868 PDEV_EXTENSION DeviceExtension;
1869 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
1870
1871 DPRINT("KsIsBusEnumChildDevice %p\n", DeviceObject);
1872
1873 /* get device extension */
1874 DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
1875
1876 /* get bus device extension */
1877 BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
1878
1879 if (!BusDeviceExtension)
1880 {
1881 /* not a bus device */
1883 }
1884
1885 /* store result */
1886 *ChildDevice = (BusDeviceExtension->Common.IsBus == FALSE);
1887
1888 return STATUS_SUCCESS;
1889}
1890
1891/*
1892 @implemented
1893*/
1896NTAPI
1899 IN OUT PIRP Irp)
1900{
1902 PBUS_DEVICE_ENTRY DeviceEntry = NULL; /* fix gcc */
1903 PIO_STACK_LOCATION IoStack;
1904 BOOLEAN ItemExists = FALSE;
1905 PDEV_EXTENSION DeviceExtension;
1906 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
1907 //PCOMMON_DEVICE_EXTENSION ChildDeviceExtension;
1910
1911 /* FIXME: locks */
1912
1913 /* get device extension */
1914 DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
1915
1916 /* get bus device extension */
1917 BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
1918
1919 /* get current irp stack location */
1921
1922 /* sanity checks */
1923 ASSERT(IoStack->FileObject);
1924 if (IoStack->FileObject->FileName.Buffer == NULL)
1925 {
1926 DPRINT("KsServiceBusEnumCreateRequest PNP Hack\n");
1927 Irp->IoStatus.Status = STATUS_SUCCESS;
1928 return STATUS_SUCCESS;
1929 }
1930
1931 ASSERT(IoStack->FileObject->FileName.Buffer);
1932
1933 DPRINT1("KsServiceBusEnumCreateRequest IRP %p Name %wZ\n", Irp, &IoStack->FileObject->FileName);
1934
1935 /* scan list and check if it is already present */
1936 Entry = BusDeviceExtension->Common.Entry.Flink;
1937
1938 while(Entry != &BusDeviceExtension->Common.Entry)
1939 {
1940 /* get real offset */
1942
1943 /* check if name matches */
1944 if (!wcsicmp(DeviceEntry->DeviceName, IoStack->FileObject->FileName.Buffer + 1))
1945 {
1946 /* item already exists */
1947 ItemExists = TRUE;
1948 break;
1949 }
1950
1951 /* move to next entry */
1952 Entry = Entry->Flink;
1953 }
1954
1955 if (!ItemExists)
1956 {
1957 /* interface not registered */
1958 DPRINT1("Interface %wZ not registered\n", &IoStack->FileObject->FileName);
1960 }
1961
1962 /* is there a pdo yet */
1963 if (DeviceEntry->PDO)
1964 {
1965 if (DeviceEntry->DeviceState == Started)
1966 {
1967 /* issue reparse */
1968 Status = KspDoReparseForIrp(Irp, DeviceEntry);
1969 DPRINT("REPARSE Irp %p '%wZ'\n", Irp, &IoStack->FileObject->FileName);
1970
1971 Irp->IoStatus.Status = Status;
1972 Irp->IoStatus.Information = IO_REPARSE;
1973 return Status;
1974 }
1975
1976 /* delay processing until pnp is finished with enumeration */
1978
1979 /* insert into irp pending list */
1980 InsertTailList(&DeviceEntry->IrpPendingList, &Irp->Tail.Overlay.ListEntry);
1981
1982 Time.QuadPart = Int32x32To64(1500, -10000);
1983 DbgPrint("PENDING Irp %p %wZ DeviceState %d\n", Irp, &IoStack->FileObject->FileName, DeviceEntry->DeviceState);
1984
1985
1986 /* set timer */
1987 KeSetTimer(&BusDeviceExtension->Timer, Time, &BusDeviceExtension->Dpc);
1988
1989 /* done for now */
1990 return STATUS_PENDING;
1991
1992 }
1993 else
1994 {
1995 /* time to create PDO */
1996 Status = KspCreatePDO(BusDeviceExtension, DeviceEntry, &DeviceEntry->PDO);
1997
1998 if (!NT_SUCCESS(Status))
1999 {
2000 /* failed to create PDO */
2001 DPRINT1("KsServiceBusEnumCreateRequest failed to create PDO with %x\n", Status);
2002 return Status;
2003 }
2004 DPRINT("PENDING CREATE Irp %p %wZ\n", Irp, &IoStack->FileObject->FileName);
2005
2006 /* delay processing until pnp is finished with enumeration */
2008
2009 /* insert into irp pending list */
2010 InsertTailList(&DeviceEntry->IrpPendingList, &Irp->Tail.Overlay.ListEntry);
2011
2012 /* invalidate device relations */
2014
2015 /* done for now */
2016 return STATUS_PENDING;
2017 }
2018}
2019
2020/*
2021 @implemented
2022*/
2025NTAPI
2028 IN OUT PIRP Irp)
2029{
2030 PDEV_EXTENSION DeviceExtension;
2031 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
2032 PCOMMON_DEVICE_EXTENSION ChildDeviceExtension;
2033 PIO_STACK_LOCATION IoStack;
2036 PDEVICE_RELATIONS DeviceRelation;
2037 PBUS_DEVICE_ENTRY DeviceEntry;
2038
2039 /* get device extension */
2040 DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
2041
2042 /* get bus device extension */
2043 BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
2044
2045 /* get current irp stack location */
2047
2048 if (BusDeviceExtension->Common.IsBus)
2049 {
2050 if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
2051 {
2052 /* no op for bus driver */
2054 }
2055 else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS)
2056 {
2057 /* handle bus device relations */
2058 ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == BusRelations);
2059
2060 Status = KspQueryBusRelations(BusDeviceExtension, Irp);
2061 }
2062 else
2063 {
2064 /* get default status */
2065 Status = Irp->IoStatus.Status;
2066 }
2067 }
2068 else
2069 {
2070 /* get child device extension */
2071 ChildDeviceExtension = DeviceExtension->Ext;
2072
2073 /* get bus device extension */
2074 BusDeviceExtension = ChildDeviceExtension->BusDeviceExtension;
2075
2076 if (IoStack->MinorFunction == IRP_MN_QUERY_ID)
2077 {
2078 /* query id */
2079 Status = KspQueryId(ChildDeviceExtension, Irp);
2080 }
2081 else if (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
2082 {
2083 ASSERT(ChildDeviceExtension->DeviceEntry->DeviceState != Started || ChildDeviceExtension->DeviceEntry->DeviceState == NotStarted);
2084 ASSERT(ChildDeviceExtension->DeviceEntry->PDO == DeviceObject);
2085
2086 /* backup device entry */
2087 DeviceEntry = ChildDeviceExtension->DeviceEntry;
2088
2089 /* free device extension */
2090 FreeItem(ChildDeviceExtension);
2091
2092 /* clear PDO reference */
2093 DeviceEntry->PDO = NULL;
2094
2095 /* delete the device */
2097
2098 if (DeviceEntry->PDODeviceName)
2099 {
2100 /* delete pdo device name */
2101 FreeItem(DeviceEntry->PDODeviceName);
2102
2103 /* set to null */
2104 DeviceEntry->PDODeviceName = NULL;
2105 }
2106
2107 /* set state no notstarted */
2108 DeviceEntry->DeviceState = NotStarted;
2109
2110 /* complete pending irps */
2112
2113 /* done */
2115 }
2116 else if (IoStack->MinorFunction == IRP_MN_QUERY_BUS_INFORMATION)
2117 {
2118 /* query bus information */
2119 Status = KspQueryBusInformation(ChildDeviceExtension, Irp);
2120 }
2121 else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES)
2122 {
2123 /* no op */
2125 }
2127 {
2128 /* no op */
2130 }
2131 else if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
2132 {
2133 /* start bus */
2134 Status = KspStartBusDevice(DeviceObject, ChildDeviceExtension, Irp);
2135 if (NT_SUCCESS(Status))
2136 {
2137 /* complete pending irps*/
2138 KspCompletePendingIrps(ChildDeviceExtension->DeviceEntry, STATUS_REPARSE);
2139 }
2140
2141 /* set time out */
2142 Time.QuadPart = Int32x32To64(1500, -10000);
2143
2144 /* sanity check */
2145 ASSERT(BusDeviceExtension);
2146
2147 /* set timer */
2148 KeSetTimer(&BusDeviceExtension->Timer, Time, &BusDeviceExtension->Dpc);
2149 }
2150 else if (IoStack->MinorFunction == IRP_MN_QUERY_CAPABILITIES)
2151 {
2152 /* query capabilities */
2153 Status = KspQueryBusDeviceCapabilities(ChildDeviceExtension, Irp);
2154 }
2155 else if (IoStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
2156 {
2157 /* query pnp state */
2158 Status = KspQueryBusDevicePnpState(ChildDeviceExtension, Irp);
2159 }
2160 else if (IoStack->MinorFunction == IRP_MN_QUERY_INTERFACE)
2161 {
2162 /* query interface */
2163 Status = KspQueryBusDeviceInterface(ChildDeviceExtension, Irp);
2164 }
2165 else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS && IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
2166 {
2167 /* handle target device relations */
2168 ASSERT(Irp->IoStatus.Information == 0);
2169
2170 /* allocate device relation */
2171 DeviceRelation = AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
2172 if (DeviceRelation)
2173 {
2174 DeviceRelation->Count = 1;
2175 DeviceRelation->Objects[0] = DeviceObject;
2176
2177 /* reference self */
2179
2180 /* store result */
2181 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
2182
2183 /* done */
2185 }
2186 else
2187 {
2188 /* no memory */
2190 }
2191 }
2192 else
2193 {
2194 /* get default status */
2195 Status = Irp->IoStatus.Status;
2196 }
2197 }
2198
2199 DPRINT("KsServiceBusEnumPnpRequest %p Bus %u Function %x Status %x\n", DeviceObject, BusDeviceExtension->Common.IsBus, IoStack->MinorFunction, Status);
2200 Irp->IoStatus.Status = Status;
2201 return Status;
2202}
2203
2204/*
2205 @implemented
2206*/
2209NTAPI
2211 IN PIRP Irp)
2212{
2214 LUID luid;
2216 PDEV_EXTENSION DeviceExtension;
2217 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
2218 PIO_STACK_LOCATION IoStack;
2219
2220 DPRINT("KsRemoveBusEnumInterface\n");
2221
2222 /* get io stack location */
2224
2225 /* get device extension */
2226 DeviceExtension = (PDEV_EXTENSION)IoStack->DeviceObject->DeviceExtension;
2227
2228 /* get bus device extension */
2229 BusDeviceExtension = DeviceExtension->Ext->BusDeviceExtension;
2230
2231 /* get previous mode */
2233
2234 /* convert to luid */
2236
2237 /* perform access check */
2238 if (!SeSinglePrivilegeCheck(luid, Mode))
2239 {
2240 /* insufficient privileges */
2242 }
2243
2244 /* initialize context */
2246 Ctx.Irp = Irp;
2247 Ctx.BusDeviceExtension = BusDeviceExtension;
2249
2250 /* now queue the work item */
2252
2253 /* wait for completion */
2255
2256 /* return result */
2257 return Ctx.Status;
2258}
struct _IRP * PIRP
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
unsigned char BOOLEAN
@ StopPending
Definition: acpisys.h:15
@ Started
Definition: acpisys.h:14
struct NameRec_ * Name
Definition: cdprocs.h:460
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:115
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NTSTATUS
Definition: precomp.h:21
#define GENERIC_READ
Definition: compat.h:135
#define wcsicmp
Definition: compat.h:15
#define swprintf
Definition: precomp.h:40
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
struct _COMMON_DEVICE_EXTENSION * PCOMMON_DEVICE_EXTENSION
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define PagedPool
Definition: env_spec_w32.h:308
#define ExGetPreviousMode
Definition: ex.h:140
@ NotStarted
Definition: fbtusb.h:80
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
#define DbgPrint
Definition: hal.h:12
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
_In_ ULONG Mode
Definition: hubbusif.h:303
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlGUIDFromString(PUNICODE_STRING, GUID *)
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
IoMarkIrpPending(Irp)
KSDDKAPI NTSTATUS NTAPI KsInstallBusEnumInterface(PIRP Irp)
Definition: swenum.c:1805
VOID NTAPI KspRemoveBusInterface(PVOID Ctx)
Definition: swenum.c:1290
NTSTATUS KspQueryId(IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension, IN PIRP Irp)
Definition: swenum.c:891
NTSTATUS KspQueryBusDeviceCapabilities(IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension, IN PIRP Irp)
Definition: swenum.c:822
NTSTATUS NTAPI KspBusQueryReferenceString(IN PVOID Context, IN OUT PWCHAR *String)
Definition: swenum.c:529
KSDDKAPI NTSTATUS NTAPI KsIsBusEnumChildDevice(IN PDEVICE_OBJECT DeviceObject, OUT PBOOLEAN ChildDevice)
Definition: swenum.c:1864
NTSTATUS NTAPI KspCreateDeviceAssociation(IN PHANDLE hKey, IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PBUS_DEVICE_ENTRY DeviceEntry, IN LPWSTR InterfaceString, IN LPWSTR ReferenceString)
Definition: swenum.c:258
VOID KspRemoveDeviceAssociations(IN PBUS_DEVICE_ENTRY DeviceEntry)
Definition: swenum.c:133
VOID NTAPI KspBusDeviceReference(IN PVOID Context)
Definition: swenum.c:565
VOID NTAPI KspBusWorkerRoutine(IN PVOID Parameter)
Definition: swenum.c:1179
VOID NTAPI KspBusDereferenceDeviceObject(IN PVOID Context)
Definition: swenum.c:598
VOID NTAPI KspBusReferenceDeviceObject(IN PVOID Context)
Definition: swenum.c:587
NTSTATUS KspQueryBusDeviceInterface(IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension, IN PIRP Irp)
Definition: swenum.c:608
VOID NTAPI KspInstallBusEnumInterface(IN PVOID Ctx)
Definition: swenum.c:1077
VOID NTAPI KspBusDeviceDereference(IN PVOID Context)
Definition: swenum.c:576
NTSTATUS KspEnableBusDeviceInterface(PBUS_DEVICE_ENTRY DeviceEntry, BOOLEAN bEnable)
Definition: swenum.c:637
KSDDKAPI NTSTATUS NTAPI KsGetBusEnumPnpDeviceObject(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT *PnpDeviceObject)
Definition: swenum.c:1751
KSDDKAPI NTSTATUS NTAPI KsGetBusEnumIdentifier(IN PIRP Irp)
Definition: swenum.c:1403
NTSTATUS KspInstallInterface(IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PSWENUM_INSTALL_INTERFACE InstallInterface)
Definition: swenum.c:985
NTSTATUS KspStartBusDevice(IN PDEVICE_OBJECT DeviceObject, IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension, IN PIRP Irp)
Definition: swenum.c:760
NTSTATUS NTAPI KspCreateDeviceReferenceTrampoline(IN PHANDLE hKey, IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PBUS_DEVICE_ENTRY DummyEntry, IN LPWSTR DeviceCategory, IN LPWSTR ReferenceString)
Definition: swenum.c:470
KSDDKAPI NTSTATUS NTAPI KsServiceBusEnumPnpRequest(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: swenum.c:2026
NTSTATUS KspCreatePDO(IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PBUS_DEVICE_ENTRY DeviceEntry, OUT PDEVICE_OBJECT *OutDeviceObject)
Definition: swenum.c:27
NTSTATUS KspEnumerateBusRegistryKeys(IN HANDLE hKey, IN LPWSTR ReferenceString, IN PKSP_BUS_ENUM_CALLBACK Callback, IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PBUS_DEVICE_ENTRY DeviceEntry)
Definition: swenum.c:168
VOID NTAPI KspBusDpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: swenum.c:1275
NTSTATUS KspDoReparseForIrp(PIRP Irp, PBUS_DEVICE_ENTRY DeviceEntry)
Definition: swenum.c:672
NTSTATUS KspQueryBusRelations(IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PIRP Irp)
Definition: swenum.c:1311
NTSTATUS(NTAPI * PKSP_BUS_ENUM_CALLBACK)(IN PHANDLE hKey, IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PBUS_DEVICE_ENTRY DummyEntry, IN LPWSTR RootName, IN LPWSTR DirectoryName)
Definition: swenum.c:19
KSDDKAPI NTSTATUS NTAPI KsServiceBusEnumCreateRequest(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: swenum.c:1897
LONG KsDeviceCount
Definition: swenum.c:17
NTSTATUS KspRegisterDeviceAssociation(IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PBUS_DEVICE_ENTRY DeviceEntry, IN OUT PBUS_INSTANCE_ENTRY BusInstanceEntry)
Definition: swenum.c:93
KSDDKAPI NTSTATUS NTAPI KsRemoveBusEnumInterface(IN PIRP Irp)
Definition: swenum.c:2210
NTSTATUS KspQueryBusDevicePnpState(IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension, IN PIRP Irp)
Definition: swenum.c:879
NTSTATUS KspScanBus(IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension)
Definition: swenum.c:495
KSDDKAPI NTSTATUS NTAPI KsGetBusEnumParentFDOFromChildPDO(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_OBJECT *FunctionalDeviceObject)
Definition: swenum.c:1489
NTSTATUS KspQueryBusInformation(IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension, IN PIRP Irp)
Definition: swenum.c:851
VOID KspCompletePendingIrps(IN PBUS_DEVICE_ENTRY DeviceEntry, IN OUT NTSTATUS ResultCode)
Definition: swenum.c:718
NTSTATUS NTAPI KspCreateDeviceReference(IN PHANDLE hKey, IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, IN PBUS_DEVICE_ENTRY DummyEntry, IN LPWSTR InterfaceId, IN LPWSTR DeviceId)
Definition: swenum.c:330
KSDDKAPI NTSTATUS NTAPI KsCreateBusEnumObject(IN PWCHAR BusIdentifier, IN PDEVICE_OBJECT BusDeviceObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL, IN REFGUID InterfaceGuid OPTIONAL, IN PWCHAR ServiceRelativePath OPTIONAL)
Definition: swenum.c:1521
NTSTATUS KspOpenBusRegistryKey(IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension, OUT PHANDLE hKey)
Definition: swenum.c:482
#define KSMEDIUMSETID_Standard
Definition: ks.h:306
#define KSDDKAPI
Definition: ks.h:40
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
struct __BUS_ENUM_DEVICE_EXTENSION__ * PBUS_ENUM_DEVICE_EXTENSION
struct BUS_INSTALL_ENUM_CONTEXT * PBUS_INSTALL_ENUM_CONTEXT
struct BUS_INSTANCE_ENTRY * PBUS_INSTANCE_ENTRY
struct DEV_EXTENSION * PDEV_EXTENSION
struct __BUS_DEVICE_ENTRY__ * PBUS_DEVICE_ENTRY
struct __BUS_ENUM_DEVICE_EXTENSION__ BUS_ENUM_DEVICE_EXTENSION
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define SE_LOAD_DRIVER_PRIVILEGE
Definition: security.c:664
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static PLARGE_INTEGER Time
Definition: time.c:105
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT * FunctionalDeviceObject
Definition: ndis.h:4641
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
int Count
Definition: noreturn.cpp:7
@ KeyBasicInformation
Definition: nt_native.h:1131
@ KeyFullInformation
Definition: nt_native.h:1133
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
struct _KEY_BASIC_INFORMATION * PKEY_BASIC_INFORMATION
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define GENERIC_WRITE
Definition: nt_native.h:90
#define Int32x32To64(a, b)
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
@ SynchronizationEvent
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
ULONG NTAPI KeQueryTimeIncrement(VOID)
Definition: clock.c:153
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
@ PowerSystemWorking
Definition: ntpoapi.h:36
@ PowerDeviceD0
Definition: ntpoapi.h:49
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_DEVICE_REMOVED
Definition: ntstatus.h:809
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:1382
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:140
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension
Definition: kstypes.h:229
WORK_QUEUE_ITEM WorkItem
Definition: kstypes.h:232
Definition: kstypes.h:171
LIST_ENTRY Entry
Definition: kstypes.h:172
UNICODE_STRING SymbolicLink
Definition: kstypes.h:174
GUID InterfaceGuid
Definition: kstypes.h:173
ULONG DeviceObjectReferenceCount
Definition: kstypes.h:162
struct __BUS_ENUM_DEVICE_EXTENSION__ * BusDeviceExtension
Definition: kstypes.h:161
PCOMMON_DEVICE_EXTENSION Ext
Definition: kstypes.h:167
base of all file and directory entries
Definition: entries.h:83
Entry(ENTRY_TYPE etype)
Definition: entries.cpp:35
PDEVICE_OBJECT DeviceObject
Definition: pci.h:46
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
Definition: scsiwmi.h:51
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: ketypes.h:699
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: kstypes.h:192
LIST_ENTRY DeviceInterfaceList
Definition: kstypes.h:194
LPWSTR PDODeviceName
Definition: kstypes.h:199
LPWSTR BusId
Definition: kstypes.h:201
LIST_ENTRY Entry
Definition: kstypes.h:193
GUID DeviceGuid
Definition: kstypes.h:198
LPWSTR DeviceName
Definition: kstypes.h:200
LPWSTR Instance
Definition: kstypes.h:204
PDEVICE_OBJECT PDO
Definition: kstypes.h:196
DEVICE_STATE DeviceState
Definition: kstypes.h:197
LARGE_INTEGER TimeCreated
Definition: kstypes.h:202
LIST_ENTRY IrpPendingList
Definition: kstypes.h:195
COMMON_DEVICE_EXTENSION Common
Definition: kstypes.h:209
UNICODE_STRING ServicePath
Definition: kstypes.h:221
PDEVICE_OBJECT PnpDeviceObject
Definition: kstypes.h:214
WORK_QUEUE_ITEM WorkItem
Definition: kstypes.h:219
UNICODE_STRING DeviceInterfaceLink
Definition: kstypes.h:212
PDEVICE_OBJECT PhysicalDeviceObject
Definition: kstypes.h:213
PDEVICE_OBJECT BusDeviceObject
Definition: kstypes.h:215
struct _SWENUM_INSTALL_INTERFACE * PSWENUM_INSTALL_INTERFACE
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ CONST GUID _In_opt_ PCUNICODE_STRING ReferenceString
Definition: wdfdevice.h:3630
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ WDFDEVICE _In_ PPNP_BUS_INFORMATION BusInformation
Definition: wdfdevice.h:3915
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
_In_ BOOL bEnable
Definition: winddi.h:3426
static const GUID InterfaceGuid
Definition: wlanapi.c:25
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
struct _PNP_BUS_INFORMATION * PPNP_BUS_INFORMATION
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_REPARSE
Definition: iotypes.h:543
DEVICE_CAPABILITIES
Definition: iotypes.h:965
@ BusRelations
Definition: iotypes.h:2152
@ TargetDeviceRelation
Definition: iotypes.h:2156
#define IRP_DEALLOCATE_BUFFER
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:1006
#define IRP_INPUT_OPERATION
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_QUERY_INTERFACE
#define IRP_MN_START_DEVICE
#define PNP_DEVICE_DONT_DISPLAY_IN_UI
Definition: iotypes.h:1002
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
#define IRP_MN_QUERY_ID
#define IRP_MN_REMOVE_DEVICE
@ DevicePropertyPhysicalDeviceObjectName
Definition: iotypes.h:1206
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define DO_POWER_PAGABLE
#define IRP_MN_QUERY_CAPABILITIES
#define IRP_MN_QUERY_RESOURCES
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
struct _DEVICE_RELATIONS DEVICE_RELATIONS
#define IRP_BUFFERED_IO
@ BusQueryInstanceID
Definition: iotypes.h:2939
@ BusQueryDeviceID
Definition: iotypes.h:2936
@ BusQueryHardwareIDs
Definition: iotypes.h:2937
#define IRP_MN_QUERY_BUS_INFORMATION
@ Executive
Definition: ketypes.h:415
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:687
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689
#define ObReferenceObject
Definition: obfuncs.h:204
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
FORCEINLINE LUID NTAPI_INLINE RtlConvertUlongToLuid(_In_ ULONG Val)
Definition: rtlfuncs.h:3541
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184