xref: /reactos/dll/win32/streamci/streamci.c (revision 0c2cdcae)
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