xref: /reactos/dll/win32/streamci/streamci.c (revision 7353af1e)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Configuration of network devices
4  * FILE:            dll/win32/streamci/streamci.c
5  * PURPOSE:         Streaming device class installer
6  *
7  * PROGRAMMERS:     Johannes Anderwald (janderwald@reactos.org)
8  */
9 
10 #include "precomp.h"
11 
12 DWORD
13 PerformIO(IN HANDLE hDevice,
14           IN DWORD dwCtlCode,
15           IN LPVOID lpBufferIn,
16           IN DWORD dwBufferSizeIn,
17           OUT LPVOID lpBufferOut,
18           OUT DWORD dwBufferSizeOut,
19           OUT LPDWORD lpNumberBytes)
20 {
21     OVERLAPPED overlapped;
22     DWORD dwResult;
23 
24     ZeroMemory(&overlapped, sizeof(OVERLAPPED));
25     overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
26     if (!overlapped.hEvent)
27     {
28         // failed to init event
29         return GetLastError();
30     }
31 
32     if (DeviceIoControl(hDevice, dwCtlCode, lpBufferIn, dwBufferSizeIn, lpBufferOut, dwBufferSizeOut, lpNumberBytes, &overlapped))
33     {
34         dwResult = ERROR_SUCCESS;
35     }
36     else if (GetLastError() == ERROR_IO_PENDING)
37     {
38         if (GetOverlappedResult(hDevice, &overlapped, lpNumberBytes, TRUE))
39         {
40             dwResult = ERROR_SUCCESS;
41         }
42         else
43         {
44             dwResult = GetLastError();
45         }
46     }
47     else
48     {
49         dwResult = GetLastError();
50     }
51     CloseHandle(overlapped.hEvent);
52     return dwResult;
53 }
54 
55 DWORD
56 InstallSoftwareDeviceInterface(IN LPGUID DeviceId,
57                                IN LPGUID InterfaceId,
58                                IN LPWSTR ReferenceString)
59 {
60     HDEVINFO hDevInfo;
61     SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
62     GUID SWBusGuid = {STATIC_BUSID_SoftwareDeviceEnumerator};
63     PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData;
64     HANDLE hDevice;
65     PSWENUM_INSTALL_INTERFACE InstallInterface;
66     DWORD dwResult;
67 
68     hDevInfo = SetupDiGetClassDevsW(&SWBusGuid, NULL, NULL,  DIGCF_DEVICEINTERFACE| DIGCF_PRESENT);
69     if (!hDevInfo)
70     {
71         // failed
72         return GetLastError();
73     }
74 
75     DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
76     if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &SWBusGuid, 0, &DeviceInterfaceData))
77     {
78         // failed
79         SetupDiDestroyDeviceInfoList(hDevInfo);
80         return GetLastError();
81     }
82 
83     DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W));
84     if (!DeviceInterfaceDetailData)
85     {
86         // failed
87         SetupDiDestroyDeviceInfoList(hDevInfo);
88         return GetLastError();
89     }
90 
91     DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
92     if (!SetupDiGetDeviceInterfaceDetailW(hDevInfo,  &DeviceInterfaceData, DeviceInterfaceDetailData,MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W), NULL, NULL))
93     {
94         // failed
95         HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
96         SetupDiDestroyDeviceInfoList(hDevInfo);
97         return GetLastError();
98     }
99 
100     hDevice = CreateFileW(DeviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL, NULL);
101     if (hDevice == INVALID_HANDLE_VALUE)
102     {
103         // failed
104         HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
105         SetupDiDestroyDeviceInfoList(hDevInfo);
106         return GetLastError();
107     }
108 
109     InstallInterface  = (PSWENUM_INSTALL_INTERFACE)HeapAlloc(GetProcessHeap(), 0, sizeof(SWENUM_INSTALL_INTERFACE) + wcslen(ReferenceString) * sizeof(WCHAR));
110     if (!InstallInterface)
111     {
112         // failed
113         CloseHandle(hDevice);
114         HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
115         SetupDiDestroyDeviceInfoList(hDevInfo);
116         return GetLastError();
117     }
118 
119     // init install interface param
120     InstallInterface->DeviceId = *DeviceId;
121     InstallInterface->InterfaceId = *InterfaceId;
122     wcscpy(InstallInterface->ReferenceString, ReferenceString);
123 
124     PerformIO(hDevice, IOCTL_SWENUM_INSTALL_INTERFACE, InstallInterface, sizeof(SWENUM_INSTALL_INTERFACE) + wcslen(ReferenceString) * sizeof(WCHAR), NULL, 0, NULL);
125     dwResult = HeapFree(GetProcessHeap(), 0, InstallInterface);
126 
127     CloseHandle(hDevice);
128     HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
129     SetupDiDestroyDeviceInfoList(hDevInfo);
130     return dwResult;
131 }
132 
133 DWORD
134 InstallSoftwareDeviceInterfaceInf(IN LPWSTR InfName,
135                                   IN LPWSTR SectionName)
136 {
137     HDEVINFO hDevInfo;
138     HINF hInf;
139     HKEY hKey;
140     SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
141     GUID SWBusGuid = {STATIC_BUSID_SoftwareDeviceEnumerator};
142 
143     hDevInfo = SetupDiGetClassDevsW(&SWBusGuid, NULL, NULL, 0);
144     if (!hDevInfo)
145     {
146         // failed
147         return GetLastError();
148     }
149 
150     DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
151     if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &SWBusGuid, 0, &DeviceInterfaceData))
152     {
153         // failed
154         return GetLastError();
155     }
156 
157     hInf = SetupOpenInfFileW(InfName, NULL, INF_STYLE_WIN4, NULL);
158     if (hInf == INVALID_HANDLE_VALUE)
159     {
160         SetupDiDestroyDeviceInfoList(hDevInfo);
161         return GetLastError();
162     }
163 
164     //
165     // FIXME check if interface is already installed
166     //
167 
168     hKey = SetupDiCreateDeviceInterfaceRegKeyW(hDevInfo, &DeviceInterfaceData, 0, KEY_ALL_ACCESS, hInf, SectionName);
169 
170     SetupCloseInfFile(hInf);
171     SetupDiDestroyDeviceInfoList(hDevInfo);
172     if (hKey != INVALID_HANDLE_VALUE)
173     {
174         RegCloseKey(hKey);
175     }
176     return ERROR_SUCCESS;
177 }
178 
179 
180 VOID
181 WINAPI
182 StreamingDeviceSetupW(IN HWND hwnd,
183                      IN HINSTANCE hinst,
184                      IN LPWSTR lpszCmdLine,
185                      IN int nCmdShow)
186 {
187     DWORD Length, dwResult;
188     LPWSTR pCmdLine;
189     LPWSTR pStr;
190     GUID Guids[2];
191     WCHAR DevicePath[MAX_PATH];
192     HRESULT hResult;
193     DWORD Index;
194 
195     Length = (wcslen(lpszCmdLine) + 1) * sizeof(WCHAR);
196 
197     pCmdLine = (LPWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
198     if (pCmdLine == NULL)
199     {
200         // no memory
201         return;
202     }
203 
204     hResult = StringCbCopyExW(pCmdLine, Length, lpszCmdLine, NULL, NULL, STRSAFE_NULL_ON_FAILURE);
205     if (hResult != S_OK)
206     {
207         // failed
208         HeapFree(GetProcessHeap(), 0, pCmdLine);
209         return;
210     }
211 
212     pStr = wcstok(pCmdLine, L",\t\"");
213     Index = 0;
214     do
215     {
216         if (pStr == NULL)
217         {
218             // invalid parameter
219             HeapFree(GetProcessHeap(), 0, pCmdLine);
220             return;
221         }
222 
223         hResult = IIDFromString(pStr, &Guids[Index]);
224         if (hResult != S_OK)
225         {
226             // invalid parameter
227             HeapFree(GetProcessHeap(), 0, pCmdLine);
228             return;
229         }
230 
231         Index++;
232         pStr = wcstok(NULL, L",\t\"");
233 
234 
235     }while(Index < 2);
236 
237 
238     dwResult = InstallSoftwareDeviceInterface(&Guids[0], &Guids[1], pStr);
239     if (dwResult == ERROR_SUCCESS)
240     {
241         pStr = wcstok(NULL, L",\t\"");
242         if (pStr != NULL)
243         {
244             wcscpy(DevicePath, pStr);
245             pStr = wcstok(NULL, L",\t\"");
246             if (pStr != NULL)
247             {
248                 dwResult = InstallSoftwareDeviceInterfaceInf(DevicePath, pStr);
249             }
250         }
251     }
252 }