1 #include "precomp.h"
2 
3 #define NDEBUG
4 #include <debug.h>
5 
6 NTSTATUS
7 KspSetDeviceInterfacesState(
8     IN PLIST_ENTRY ListHead,
9     IN BOOL Enable)
10 {
11     NTSTATUS Status = STATUS_SUCCESS;
12     PLIST_ENTRY Entry;
13     PSYMBOLIC_LINK_ENTRY SymEntry;
14 
15 
16     Entry = ListHead->Flink;
17     while(Entry != ListHead)
18     {
19         /* fetch symbolic link entry */
20         SymEntry = (PSYMBOLIC_LINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLIC_LINK_ENTRY, Entry);
21         /* set device interface state */
22         Status = IoSetDeviceInterfaceState(&SymEntry->SymbolicLink, Enable);
23 
24         DPRINT("KspSetDeviceInterfacesState SymbolicLink '%S' Status %lx\n", SymEntry->SymbolicLink.Buffer, Status, Enable);
25 
26         /* check for success */
27         if (!NT_SUCCESS(Status))
28             return Status;
29         /* get next entry */
30         Entry = Entry->Flink;
31     }
32     /* return result */
33     return Status;
34 }
35 
36 NTSTATUS
37 KspFreeDeviceInterfaces(
38     IN PLIST_ENTRY ListHead)
39 {
40     PLIST_ENTRY Entry;
41     PSYMBOLIC_LINK_ENTRY SymEntry;
42 
43     while(!IsListEmpty(ListHead))
44     {
45         /* remove first entry */
46         Entry = RemoveHeadList(ListHead);
47 
48         /* fetch symbolic link entry */
49         SymEntry = (PSYMBOLIC_LINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLIC_LINK_ENTRY, Entry);
50 
51         /* free device interface string */
52         RtlFreeUnicodeString(&SymEntry->SymbolicLink);
53         /* free entry item */
54         FreeItem(Entry);
55     }
56 
57     return STATUS_SUCCESS;
58 }
59 
60 NTSTATUS
61 KspRegisterDeviceInterfaces(
62     IN PDEVICE_OBJECT PhysicalDeviceObject,
63     IN ULONG CategoriesCount,
64     IN GUID const*Categories,
65     IN PUNICODE_STRING ReferenceString,
66     OUT PLIST_ENTRY SymbolicLinkList)
67 {
68     ULONG Index;
69     NTSTATUS Status = STATUS_SUCCESS;
70     PSYMBOLIC_LINK_ENTRY SymEntry;
71 
72     for(Index = 0; Index < CategoriesCount; Index++)
73     {
74         /* allocate a symbolic link entry */
75         SymEntry = AllocateItem(NonPagedPool, sizeof(SYMBOLIC_LINK_ENTRY));
76         /* check for success */
77         if (!SymEntry)
78             return STATUS_INSUFFICIENT_RESOURCES;
79 
80         /* now register device interface */
81         Status = IoRegisterDeviceInterface(PhysicalDeviceObject,
82                                            &Categories[Index],
83                                            ReferenceString,
84                                            &SymEntry->SymbolicLink);
85 
86         if (!NT_SUCCESS(Status))
87         {
88             DPRINT1("Failed to register device interface %x\n", Status);
89 
90             /* free entry */
91             FreeItem(SymEntry);
92 
93             /* return result */
94             return Status;
95         }
96 
97         /* copy device class */
98         RtlMoveMemory(&SymEntry->DeviceInterfaceClass, &Categories[Index], sizeof(CLSID));
99 
100         /* insert symbolic link entry */
101         InsertTailList(SymbolicLinkList, &SymEntry->Entry);
102     }
103 
104     /* return result */
105     return Status;
106 }
107 
108 NTSTATUS
109 KspSetFilterFactoriesState(
110     IN PKSIDEVICE_HEADER DeviceHeader,
111     IN BOOLEAN NewState)
112 {
113     PCREATE_ITEM_ENTRY CreateEntry;
114     PLIST_ENTRY Entry;
115     NTSTATUS Status = STATUS_SUCCESS;
116 
117     /* grab first device interface */
118     Entry = DeviceHeader->ItemList.Flink;
119     while(Entry != &DeviceHeader->ItemList && Status == STATUS_SUCCESS)
120     {
121         /* grab create entry */
122         CreateEntry = CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry);
123 
124         /* sanity check */
125         ASSERT(CreateEntry->CreateItem);
126 
127         if (CreateEntry->CreateItem->Create == IKsFilterFactory_Create)
128         {
129             /* found our own filterfactory */
130             Status = KsFilterFactorySetDeviceClassesState((PKSFILTERFACTORY)CreateEntry->CreateItem->Context, NewState);
131         }
132 
133         Entry = Entry->Flink;
134     }
135 
136     /* store result */
137     return Status;
138 }
139