[SHELL32] CDrivesFolder: Implement the eject and disconnect menu items. CORE-13841
[reactos.git] / dll / win32 / streamci / streamci.c
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 }