ReactOS  0.4.14-dev-358-gbef841c
netinstall.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * PURPOSE: System setup
5  * FILE: dll/win32/syssetup/netinstall.c
6  * PROGRAMER: Eric Kohl
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include "precomp.h"
12 
13 #include <rpc.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 typedef struct _COMPONENT_INFO
19 {
27 
28 
29 /* GLOBALS ******************************************************************/
30 
31 
32 /* FUNCTIONS ****************************************************************/
33 
34 static
35 BOOL
37  _In_ HWND hWnd,
38  _In_ HKEY hKey,
39  _In_ LPCWSTR InfFile,
40  _In_ LPCWSTR InfSection)
41 {
45  PVOID Context = NULL;
46  BOOL ret = FALSE;
47 
48  DPRINT("InstallInfSections()\n");
49 
50  if (InfSection == NULL)
51  return FALSE;
52 
53  /* Get Windows directory */
54  BufferSize = ARRAYSIZE(Buffer) - 5 - wcslen(InfFile);
56  {
57  /* Function failed */
59  goto cleanup;
60  }
61 
62  /* We have enough space to add some information in the buffer */
63  if (Buffer[wcslen(Buffer) - 1] != '\\')
64  wcscat(Buffer, L"\\");
65  wcscat(Buffer, L"Inf\\");
66  wcscat(Buffer, InfFile);
67 
68  /* Install specified section */
70  if (hInf == INVALID_HANDLE_VALUE)
71  goto cleanup;
72 
74  if (Context == NULL)
75  goto cleanup;
76 
78  hWnd, hInf,
79  InfSection, SPINST_ALL,
80  hKey, NULL, SP_COPY_NEWER,
82  NULL, NULL);
83  if (ret == FALSE)
84  {
85  DPRINT1("SetupInstallFromInfSectionW(%S) failed (Error %lx)\n", InfSection, GetLastError());
86  goto cleanup;
87  }
88 
89  wcscpy(Buffer, InfSection);
90  wcscat(Buffer, L".Services");
91 
93  if (ret == FALSE)
94  {
95  DPRINT1("SetupInstallServicesFromInfSectionW(%S) failed (Error %lx)\n", Buffer, GetLastError());
96  goto cleanup;
97  }
98 
99 cleanup:
100  if (Context)
102 
103  if (hInf != INVALID_HANDLE_VALUE)
104  SetupCloseInfFile(hInf);
105 
106  DPRINT("InstallInfSections() done %u\n", ret);
107 
108  return ret;
109 }
110 
111 
112 static
113 BOOL
115  _In_ PCOMPONENT_INFO pComponentInfo,
116  _Out_ PHKEY pInstanceKey)
117 {
118  WCHAR szKeyBuffer[128];
119  LPWSTR UuidString = NULL;
120  UUID Uuid;
121  RPC_STATUS RpcStatus;
122  HKEY hInstanceKey;
123  DWORD rc;
124  BOOL ret = FALSE;
125 
126  DPRINT("CreateInstanceKey()\n");
127 
128  *pInstanceKey = NULL;
129 
130  wcscpy(szKeyBuffer, L"SYSTEM\\CurrentControlSet\\Control\\Network\\");
131  wcscat(szKeyBuffer, pComponentInfo->pszClassGuid);
132  wcscat(szKeyBuffer, L"\\{");
133 
134  /* Create a new UUID */
135  RpcStatus = UuidCreate(&Uuid);
136  if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY)
137  {
138  DPRINT1("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus);
139  goto done;
140  }
141 
142  RpcStatus = UuidToStringW(&Uuid, &UuidString);
143  if (RpcStatus != RPC_S_OK)
144  {
145  DPRINT1("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus);
146  goto done;
147  }
148 
149  wcscat(szKeyBuffer, UuidString);
150  wcscat(szKeyBuffer, L"}");
151 
152  RpcStringFreeW(&UuidString);
153 
154  DPRINT("szKeyBuffer %S\n", szKeyBuffer);
155 
157  szKeyBuffer,
158  0,
159  NULL,
162  NULL,
163  &hInstanceKey,
164  NULL);
165  if (rc != ERROR_SUCCESS)
166  {
167  DPRINT1("RegCreateKeyExW() failed with error 0x%lx\n", rc);
168  goto done;
169  }
170 
171  rc = RegSetValueExW(hInstanceKey,
172  L"Characteristics",
173  0,
174  REG_DWORD,
175  (LPBYTE)&pComponentInfo->dwCharacteristics,
176  sizeof(DWORD));
177  if (rc != ERROR_SUCCESS)
178  {
179  DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc);
180  goto done;
181  }
182 
183  rc = RegSetValueExW(hInstanceKey,
184  L"ComponentId",
185  0,
186  REG_SZ,
187  (LPBYTE)pComponentInfo->pszComponentId,
188  (wcslen(pComponentInfo->pszComponentId) + 1) * sizeof(WCHAR));
189  if (rc != ERROR_SUCCESS)
190  {
191  DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc);
192  goto done;
193  }
194 
195  rc = RegSetValueExW(hInstanceKey,
196  L"Description",
197  0,
198  REG_SZ,
199  (LPBYTE)pComponentInfo->pszDescription,
200  (wcslen(pComponentInfo->pszDescription) + 1) * sizeof(WCHAR));
201  if (rc != ERROR_SUCCESS)
202  {
203  DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc);
204  goto done;
205  }
206 
207  rc = RegSetValueExW(hInstanceKey,
208  L"InfPath",
209  0,
210  REG_SZ,
211  (LPBYTE)pComponentInfo->pszInfPath,
212  (wcslen(pComponentInfo->pszInfPath) + 1) * sizeof(WCHAR));
213  if (rc != ERROR_SUCCESS)
214  {
215  DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc);
216  goto done;
217  }
218 
219  rc = RegSetValueExW(hInstanceKey,
220  L"InfSection",
221  0,
222  REG_SZ,
223  (LPBYTE)pComponentInfo->pszInfSection,
224  (wcslen(pComponentInfo->pszInfSection) + 1) * sizeof(WCHAR));
225  if (rc != ERROR_SUCCESS)
226  {
227  DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc);
228  goto done;
229  }
230 
231  *pInstanceKey = hInstanceKey;
232  ret = TRUE;
233 
234 done:
235  if (ret == FALSE)
236  RegCloseKey(hInstanceKey);
237 
238  DPRINT("CreateInstanceKey() done %u\n", ret);
239 
240  return ret;
241 }
242 
243 
244 static
245 BOOL
247  _In_ PWSTR pszFullInfName,
248  _In_ PWSTR pszComponentId,
249  _In_ PCOMPONENT_INFO pComponentInfo)
250 {
251  WCHAR szLineBuffer[MAX_PATH];
252  HINF hInf = INVALID_HANDLE_VALUE;
253  INFCONTEXT MfgContext, DevContext, MiscContext;
254  DWORD dwLength;
255 
256  hInf = SetupOpenInfFileW(pszFullInfName,
257  NULL,
259  NULL);
260  if (hInf == INVALID_HANDLE_VALUE)
261  {
262  DPRINT1("\n");
263  return FALSE;
264  }
265 
266  if (!SetupFindFirstLineW(hInf,
267  L"Manufacturer",
268  NULL,
269  &MfgContext))
270  {
271  DPRINT("No Manufacurer section found!\n");
272  goto done;
273  }
274 
275  for (;;)
276  {
277  if (!SetupGetStringFieldW(&MfgContext,
278  1,
279  szLineBuffer,
280  MAX_PATH,
281  NULL))
282  break;
283 
284  DPRINT("Manufacturer: %S\n", szLineBuffer);
285  if (!SetupFindFirstLineW(hInf,
286  szLineBuffer,
287  NULL,
288  &DevContext))
289  break;
290 
291  for (;;)
292  {
293  if (!SetupGetStringFieldW(&DevContext,
294  2,
295  szLineBuffer,
296  MAX_PATH,
297  NULL))
298  break;
299 
300  DPRINT("Device: %S\n", szLineBuffer);
301  if (_wcsicmp(szLineBuffer, pszComponentId) == 0)
302  {
303  DPRINT("Found it!\n");
304 
305  /* Get the section name*/
306  SetupGetStringFieldW(&DevContext,
307  1,
308  NULL,
309  0,
310  &dwLength);
311 
312  pComponentInfo->pszInfSection = HeapAlloc(GetProcessHeap(),
313  0,
314  dwLength * sizeof(WCHAR));
315  if (pComponentInfo->pszInfSection)
316  {
317  SetupGetStringFieldW(&DevContext,
318  1,
319  pComponentInfo->pszInfSection,
320  dwLength,
321  &dwLength);
322  }
323 
324  /* Get the description*/
325  SetupGetStringFieldW(&DevContext,
326  0,
327  NULL,
328  0,
329  &dwLength);
330 
331  pComponentInfo->pszDescription = HeapAlloc(GetProcessHeap(),
332  0,
333  dwLength * sizeof(WCHAR));
334  if (pComponentInfo->pszDescription)
335  {
336  SetupGetStringFieldW(&DevContext,
337  0,
338  pComponentInfo->pszDescription,
339  dwLength,
340  &dwLength);
341  }
342 
343  /* Get the class GUID */
344  if (SetupFindFirstLineW(hInf,
345  L"Version",
346  L"ClassGuid",
347  &MiscContext))
348  {
349  SetupGetStringFieldW(&MiscContext,
350  1,
351  NULL,
352  0,
353  &dwLength);
354 
355  pComponentInfo->pszClassGuid = HeapAlloc(GetProcessHeap(),
356  0,
357  dwLength * sizeof(WCHAR));
358  if (pComponentInfo->pszInfSection)
359  {
360  SetupGetStringFieldW(&MiscContext,
361  1,
362  pComponentInfo->pszClassGuid,
363  dwLength,
364  &dwLength);
365  }
366  }
367 
368  /* Get the Characteristics value */
369  if (SetupFindFirstLineW(hInf,
370  pComponentInfo->pszInfSection,
371  L"Characteristics",
372  &MiscContext))
373  {
374  SetupGetIntField(&MiscContext,
375  1,
376  (PINT)&pComponentInfo->dwCharacteristics);
377  }
378 
379  SetupCloseInfFile(hInf);
380  return TRUE;
381  }
382 
383  if (!SetupFindNextLine(&DevContext, &DevContext))
384  break;
385  }
386 
387  if (!SetupFindNextLine(&MfgContext, &MfgContext))
388  break;
389  }
390 
391 done:
392  if (hInf != INVALID_HANDLE_VALUE)
393  SetupCloseInfFile(hInf);
394 
395  return FALSE;
396 }
397 
398 
399 static
400 BOOL
402  _In_ PWSTR pszComponentId,
403  _In_ PCOMPONENT_INFO pComponentInfo)
404 {
405  WCHAR szInfPath[MAX_PATH];
406  WCHAR szFullInfName[MAX_PATH];
407  WCHAR szPathBuffer[MAX_PATH];
408  WIN32_FIND_DATAW fdw;
409  HANDLE hFindFile = INVALID_HANDLE_VALUE;
410  BOOL bFound = FALSE;
411 
412  GetWindowsDirectoryW(szInfPath, MAX_PATH);
413  wcscat(szInfPath, L"\\inf");
414 
415  wcscpy(szPathBuffer, szInfPath);
416  wcscat(szPathBuffer, L"\\*.inf");
417 
418  hFindFile = FindFirstFileW(szPathBuffer, &fdw);
419  if (hFindFile == INVALID_HANDLE_VALUE)
420  return FALSE;
421 
422  for (;;)
423  {
424  if (wcscmp(fdw.cFileName, L".") == 0 ||
425  wcscmp(fdw.cFileName, L"..") == 0)
426  continue;
427 
428  DPRINT("FileName: %S\n", fdw.cFileName);
429 
430  wcscpy(szFullInfName, szInfPath);
431  wcscat(szFullInfName, L"\\");
432  wcscat(szFullInfName, fdw.cFileName);
433 
434  DPRINT("Full Inf Name: %S\n", szFullInfName);
435  if (CheckInfFile(szFullInfName,
436  pszComponentId,
437  pComponentInfo))
438  {
439  pComponentInfo->pszInfPath = HeapAlloc(GetProcessHeap(),
440  0,
441  (wcslen(fdw.cFileName) + 1) * sizeof(WCHAR));
442  if (pComponentInfo->pszInfPath)
443  wcscpy(pComponentInfo->pszInfPath, fdw.cFileName);
444 
445  pComponentInfo->pszComponentId = HeapAlloc(GetProcessHeap(),
446  0,
447  (wcslen(pszComponentId) + 1) * sizeof(WCHAR));
448  if (pComponentInfo->pszComponentId)
449  wcscpy(pComponentInfo->pszComponentId, pszComponentId);
450 
451  bFound = TRUE;
452  break;
453  }
454 
455  if (!FindNextFileW(hFindFile, &fdw))
456  break;
457  }
458 
459  if (hFindFile != INVALID_HANDLE_VALUE)
460  FindClose(hFindFile);
461 
462  return bFound;
463 }
464 
465 
466 BOOL
468  _In_ PWSTR pszComponentId)
469 {
471  HKEY hInstanceKey = NULL;
472  BOOL bResult = FALSE;
473 
474  DPRINT("InstallNetworkComponent(%S)\n", pszComponentId);
475 
477 
478  if (!ScanForInfFile(pszComponentId, &ComponentInfo))
479  goto done;
480 
481  DPRINT("Characteristics: 0x%lx\n", ComponentInfo.dwCharacteristics);
482  DPRINT("ComponentId: %S\n", ComponentInfo.pszComponentId);
483  DPRINT("Description: %S\n", ComponentInfo.pszDescription);
484  DPRINT("InfPath: %S\n", ComponentInfo.pszInfPath);
485  DPRINT("InfSection: %S\n", ComponentInfo.pszInfSection);
486  DPRINT("ClassGuid: %S\n", ComponentInfo.pszClassGuid);
487 
489  &hInstanceKey))
490  {
491  DPRINT1("CreateInstanceKey() failed (Error %lx)\n", GetLastError());
492  goto done;
493  }
494 
496  hInstanceKey,
497  ComponentInfo.pszInfPath,
498  ComponentInfo.pszInfSection))
499  {
500  DPRINT1("InstallInfSections() failed (Error %lx)\n", GetLastError());
501  goto done;
502  }
503 
504  bResult = TRUE;
505 
506 done:
507  if (hInstanceKey != NULL)
508  RegCloseKey(hInstanceKey);
509 
510  if (ComponentInfo.pszInfPath)
511  HeapFree(GetProcessHeap(), 0, ComponentInfo.pszInfPath);
512 
513  if (ComponentInfo.pszInfSection)
514  HeapFree(GetProcessHeap(), 0, ComponentInfo.pszInfSection);
515 
516  if (ComponentInfo.pszComponentId)
517  HeapFree(GetProcessHeap(), 0, ComponentInfo.pszComponentId);
518 
519  if (ComponentInfo.pszDescription)
520  HeapFree(GetProcessHeap(), 0, ComponentInfo.pszDescription);
521 
522  if (ComponentInfo.pszClassGuid)
523  HeapFree(GetProcessHeap(), 0, ComponentInfo.pszClassGuid);
524 
525  return bResult;
526 }
527 
528 /* EOF */
PWSTR pszInfPath
Definition: netinstall.c:20
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
BOOL WINAPI SetupFindFirstLineW(IN HINF InfHandle, IN PCWSTR Section, IN PCWSTR Key, IN OUT PINFCONTEXT Context)
Definition: infsupp.c:54
struct _COMPONENT_INFO COMPONENT_INFO
#define TRUE
Definition: types.h:120
PWSTR pszComponentId
Definition: netinstall.c:22
#define INF_STYLE_WIN4
Definition: infsupp.h:41
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_SET_VALUE
Definition: nt_native.h:1017
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
DWORD dwCharacteristics
Definition: netinstall.c:25
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:177
uint16_t * PWSTR
Definition: typedefs.h:54
BOOL InstallNetworkComponent(_In_ PWSTR pszComponentId)
Definition: netinstall.c:467
HWND hWnd
Definition: settings.c:17
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
HINF WINAPI SetupOpenInfFileW(PCWSTR name, PCWSTR class, DWORD style, UINT *error)
Definition: parser.c:1229
VOID WINAPI SetupCloseInfFile(IN HINF InfHandle)
Definition: infsupp.c:43
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2351
long RPC_STATUS
Definition: rpc.h:52
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
PWSTR pszClassGuid
Definition: netinstall.c:24
struct _COMPONENT_INFO * PCOMPONENT_INFO
#define SP_COPY_NEWER
Definition: setupapi.h:473
unsigned int BOOL
Definition: ntddk_ex.h:94
static BOOL CreateInstanceKey(_In_ PCOMPONENT_INFO pComponentInfo, _Out_ PHKEY pInstanceKey)
Definition: netinstall.c:114
smooth NULL
Definition: ftsmooth.c:416
#define _Out_
Definition: no_sal2.h:323
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
PWSTR pszInfSection
Definition: netinstall.c:21
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
int * PINT
Definition: windef.h:177
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD DWORD * dwLength
Definition: fusion.c:85
#define MAX_PATH
Definition: compat.h:26
#define BufferSize
Definition: classpnp.h:419
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, RPC_WSTR *StringUuid)
Definition: rpcrt4_main.c:541
BOOL WINAPI SetupInstallFromInfSectionW(HWND owner, HINF hinf, PCWSTR section, UINT flags, HKEY key_root, PCWSTR src_root, UINT copy_flags, PSP_FILE_CALLBACK_W callback, PVOID context, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data)
Definition: install.c:1324
int ret
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
UINT WINAPI SetupDefaultQueueCallbackW(PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:1777
PWSTR pszDescription
Definition: netinstall.c:23
static BOOL InstallInfSections(_In_ HWND hWnd, _In_ HKEY hKey, _In_ LPCWSTR InfFile, _In_ LPCWSTR InfSection)
Definition: netinstall.c:36
void WINAPI SetupTermDefaultQueueCallback(PVOID context)
Definition: queue.c:1704
#define SPINST_ALL
Definition: setupapi.h:596
#define _In_
Definition: no_sal2.h:204
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
Definition: rpcrt4_main.c:306
BOOL WINAPI SetupInstallServicesFromInfSectionW(HINF Inf, PCWSTR SectionName, DWORD Flags)
Definition: install.c:1609
PVOID WINAPI SetupInitDefaultQueueCallback(HWND owner)
Definition: queue.c:1677
static BOOL CheckInfFile(_In_ PWSTR pszFullInfName, _In_ PWSTR pszComponentId, _In_ PCOMPONENT_INFO pComponentInfo)
Definition: netinstall.c:246
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI SetupFindNextLine(IN PINFCONTEXT ContextIn, OUT PINFCONTEXT ContextOut)
Definition: infsupp.c:80
#define DPRINT1
Definition: precomp.h:8
BOOL WINAPI SetupGetIntField(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT INT *IntegerValue)
Definition: infsupp.c:146
char * cleanup(char *str)
Definition: wpickclick.c:99
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static BOOL ScanForInfFile(_In_ PWSTR pszComponentId, _In_ PCOMPONENT_INFO pComponentInfo)
Definition: netinstall.c:401
#define REG_DWORD
Definition: sdbapi.c:596
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:402
#define RPC_S_UUID_LOCAL_ONLY
Definition: winerror.h:1131
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define RPC_S_OK
Definition: rpcnterr.h:22
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI SetupGetStringFieldW(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PWSTR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:184