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