ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

netcfgx.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS Configuration of network devices
00004  * FILE:            dll/win32/netcfgx/netcfgx.c
00005  * PURPOSE:         Network devices installer
00006  *
00007  * PROGRAMMERS:     Hervé Poussineau (hpoussin@reactos.org)
00008  */
00009 
00010 #include "precomp.h"
00011 
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 HINSTANCE netcfgx_hInstance;
00016 const GUID CLSID_TcpipConfigNotifyObject      = {0xA907657F, 0x6FDF, 0x11D0, {0x8E, 0xFB, 0x00, 0xC0, 0x4F, 0xD9, 0x12, 0xB2}};
00017 
00018 static INTERFACE_TABLE InterfaceTable[] =
00019 {
00020     {
00021         &CLSID_CNetCfg,
00022         INetCfg_Constructor
00023     },
00024     {
00025         &CLSID_TcpipConfigNotifyObject,
00026         TcpipConfigNotify_Constructor
00027     },
00028     {
00029         NULL,
00030         NULL
00031     }
00032 };
00033 
00034 BOOL
00035 WINAPI
00036 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
00037 {
00038     switch (fdwReason)
00039     {
00040         case DLL_PROCESS_ATTACH:
00041             netcfgx_hInstance = hinstDLL;
00042             DisableThreadLibraryCalls(netcfgx_hInstance);
00043             break;
00044     default:
00045         break;
00046     }
00047 
00048     return TRUE;
00049 }
00050 
00051 HRESULT
00052 WINAPI
00053 DllCanUnloadNow(void)
00054 {
00055     return S_FALSE;
00056 }
00057 
00058 STDAPI
00059 DllRegisterServer(void)
00060 {
00061     HKEY hKey, hSubKey;
00062     LPOLESTR pStr;
00063     WCHAR szName[MAX_PATH] = L"CLSID\\";
00064 
00065     if (FAILED(StringFromCLSID(&CLSID_CNetCfg, &pStr)))
00066         return SELFREG_E_CLASS;
00067 
00068     wcscpy(&szName[6], pStr);
00069     CoTaskMemFree(pStr);
00070 
00071     if (RegCreateKeyExW(HKEY_CLASSES_ROOT, szName, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
00072         return SELFREG_E_CLASS;
00073 
00074     if (RegCreateKeyExW(hKey, L"InProcServer32", 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
00075     {
00076         if (!GetModuleFileNameW(netcfgx_hInstance, szName, sizeof(szName)/sizeof(WCHAR)))
00077         {
00078             RegCloseKey(hSubKey);
00079             RegCloseKey(hKey);
00080             return SELFREG_E_CLASS;
00081         }
00082         szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0';
00083         RegSetValueW(hSubKey, NULL, REG_SZ, szName, (wcslen(szName)+1) * sizeof(WCHAR));
00084         RegSetValueExW(hSubKey, L"ThreadingModel", 0, REG_SZ, (LPBYTE)L"Both", 10);
00085         RegCloseKey(hSubKey);
00086     }
00087 
00088     RegCloseKey(hKey);
00089     return S_OK;
00090 }
00091 
00092 STDAPI
00093 DllUnregisterServer(void)
00094 {
00095     //FIXME
00096     // implement unregistering services
00097     //
00098     return S_OK;
00099 }
00100 
00101 STDAPI
00102 DllGetClassObject(
00103   REFCLSID rclsid,
00104   REFIID riid,
00105   LPVOID* ppv 
00106 )
00107 {
00108     UINT i;
00109     HRESULT hres = E_OUTOFMEMORY;
00110     IClassFactory * pcf = NULL; 
00111 
00112     if (!ppv)
00113         return E_INVALIDARG;
00114 
00115     *ppv = NULL;
00116 
00117     for (i = 0; InterfaceTable[i].riid; i++) 
00118     {
00119         if (IsEqualIID(InterfaceTable[i].riid, rclsid)) 
00120         {
00121             pcf = IClassFactory_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL);
00122             break;
00123         }
00124     }
00125 
00126     if (!pcf) 
00127     {
00128         return CLASS_E_CLASSNOTAVAILABLE;
00129     }
00130 
00131     hres = IClassFactory_QueryInterface(pcf, riid, ppv);
00132     IClassFactory_Release(pcf);
00133 
00134     return hres;
00135 }
00136 
00137 
00138 /* Append a REG_SZ to an existing REG_MULTI_SZ string in the registry.
00139  * If the value doesn't exist, create it.
00140  * Returns ERROR_SUCCESS if success. Othewise, returns an error code
00141  */
00142 static LONG
00143 AppendStringToMultiSZ(
00144     IN HKEY hKey,
00145     IN PCWSTR ValueName,
00146     IN PCWSTR ValueToAppend)
00147 {
00148     PWSTR Buffer = NULL;
00149     DWORD dwRegType;
00150     DWORD dwRequired, dwLength;
00151     DWORD dwTmp;
00152     LONG rc;
00153 
00154     rc = RegQueryValueExW(
00155         hKey,
00156         ValueName,
00157         NULL,
00158         &dwRegType,
00159         NULL,
00160         &dwRequired);
00161     if (rc != ERROR_FILE_NOT_FOUND)
00162     {
00163         if (rc != ERROR_SUCCESS)
00164             goto cleanup;
00165         if (dwRegType != REG_MULTI_SZ)
00166         {
00167             rc = ERROR_GEN_FAILURE;
00168             goto cleanup;
00169         }
00170 
00171         dwTmp = dwLength = dwRequired + wcslen(ValueToAppend) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
00172         Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
00173         if (!Buffer)
00174         {
00175             rc = ERROR_NOT_ENOUGH_MEMORY;
00176             goto cleanup;
00177         }
00178         rc = RegQueryValueExW(
00179             hKey,
00180             ValueName,
00181             NULL,
00182             NULL,
00183             (BYTE*)Buffer,
00184             &dwTmp);
00185         if (rc != ERROR_SUCCESS)
00186             goto cleanup;
00187     }
00188     else
00189     {
00190         dwRequired = sizeof(WCHAR);
00191         dwLength = wcslen(ValueToAppend) * sizeof(WCHAR) + 2 * sizeof(UNICODE_NULL);
00192         Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
00193         if (!Buffer)
00194         {
00195             rc = ERROR_NOT_ENOUGH_MEMORY;
00196             goto cleanup;
00197         }
00198     }
00199 
00200     /* Append the value */
00201     wcscpy(&Buffer[dwRequired / sizeof(WCHAR) - 1], ValueToAppend);
00202     /* Terminate the REG_MULTI_SZ string */
00203     Buffer[dwLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
00204 
00205     rc = RegSetValueExW(
00206         hKey,
00207         ValueName,
00208         0,
00209         REG_MULTI_SZ,
00210         (const BYTE*)Buffer,
00211         dwLength);
00212 
00213 cleanup:
00214     HeapFree(GetProcessHeap(), 0, Buffer);
00215     return rc;
00216 }
00217 
00218 /* Install a section of a .inf file
00219  * Returns TRUE if success, FALSE if failure. Error code can
00220  * be retrieved with GetLastError()
00221  */
00222 static BOOL
00223 InstallInfSection(
00224     IN HWND hWnd,
00225     IN LPCWSTR InfFile,
00226     IN LPCWSTR InfSection OPTIONAL,
00227     IN LPCWSTR InfService OPTIONAL)
00228 {
00229     WCHAR Buffer[MAX_PATH];
00230     HINF hInf = INVALID_HANDLE_VALUE;
00231     UINT BufferSize;
00232     PVOID Context = NULL;
00233     BOOL ret = FALSE;
00234 
00235     /* Get Windows directory */
00236     BufferSize = MAX_PATH - 5 - wcslen(InfFile);
00237     if (GetWindowsDirectoryW(Buffer, BufferSize) > BufferSize)
00238     {
00239         /* Function failed */
00240         SetLastError(ERROR_GEN_FAILURE);
00241         goto cleanup;
00242     }
00243     /* We have enough space to add some information in the buffer */
00244     if (Buffer[wcslen(Buffer) - 1] != '\\')
00245         wcscat(Buffer, L"\\");
00246     wcscat(Buffer, L"Inf\\");
00247     wcscat(Buffer, InfFile);
00248 
00249     /* Install specified section */
00250     hInf = SetupOpenInfFileW(Buffer, NULL, INF_STYLE_WIN4, NULL);
00251     if (hInf == INVALID_HANDLE_VALUE)
00252         goto cleanup;
00253 
00254     Context = SetupInitDefaultQueueCallback(hWnd);
00255     if (Context == NULL)
00256         goto cleanup;
00257 
00258     ret = TRUE;
00259     if (ret && InfSection)
00260     {
00261         ret = SetupInstallFromInfSectionW(
00262             hWnd, hInf,
00263             InfSection, SPINST_ALL,
00264             NULL, NULL, SP_COPY_NEWER,
00265             SetupDefaultQueueCallbackW, Context,
00266             NULL, NULL);
00267     }
00268     if (ret && InfService)
00269     {
00270         ret = SetupInstallServicesFromInfSectionW(
00271             hInf, InfService, 0);
00272     }
00273 
00274 cleanup:
00275     if (Context)
00276         SetupTermDefaultQueueCallback(Context);
00277     if (hInf != INVALID_HANDLE_VALUE)
00278         SetupCloseInfFile(hInf);
00279     return ret;
00280 }
00281 
00282 /* Add default services for network cards */
00283 static DWORD
00284 InstallAdditionalServices(
00285     IN HWND hWnd)
00286 {
00287     BOOL ret;
00288     UNICODE_STRING TcpipServicePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip");
00289 
00290     /* Install TCP/IP protocol */
00291     ret = InstallInfSection(
00292         hWnd,
00293         L"nettcpip.inf",
00294         L"MS_TCPIP.PrimaryInstall",
00295         L"MS_TCPIP.PrimaryInstall.Services");
00296     if (!ret && GetLastError() != ERROR_FILE_NOT_FOUND)
00297     {
00298         DPRINT("InstallInfSection() failed with error 0x%lx\n", GetLastError());
00299         return GetLastError();
00300     }
00301     else if (ret)
00302     {
00303         /* Start the TCP/IP driver */
00304         ret = NtLoadDriver(&TcpipServicePath);
00305         if (ret)
00306         {
00307             /* This isn't really fatal but we want to warn anyway */
00308             DPRINT1("NtLoadDriver(TCPIP) failed with NTSTATUS 0x%lx\n", (NTSTATUS)ret);
00309         }
00310     }
00311         
00312 
00313     /* You can add here more clients (SMB...) and services (DHCP server...) */
00314 
00315     return ERROR_SUCCESS;
00316 }
00317 
00318 static DWORD
00319 InstallNetDevice(
00320     IN HDEVINFO DeviceInfoSet,
00321     IN PSP_DEVINFO_DATA DeviceInfoData,
00322     LPCWSTR UuidString,
00323     DWORD Characteristics,
00324     LPCWSTR BusType)
00325 {
00326     LPWSTR InstanceId = NULL;
00327     LPWSTR DeviceName = NULL;
00328     LPWSTR ExportName = NULL;
00329     LONG rc;
00330     HKEY hKey = NULL;
00331     HKEY hNetworkKey = NULL;
00332     HKEY hLinkageKey = NULL;
00333     HKEY hConnectionKey = NULL;
00334     DWORD dwShowIcon, dwLength, dwValue;
00335     WCHAR szBuffer[300];
00336 
00337     /* Get Instance ID */
00338     if (SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, NULL, 0, &dwLength))
00339     {
00340         DPRINT("SetupDiGetDeviceInstanceIdW() returned TRUE. FALSE expected\n");
00341         rc = ERROR_GEN_FAILURE;
00342         goto cleanup;
00343     }
00344     InstanceId = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
00345     if (!InstanceId)
00346     {
00347         DPRINT("HeapAlloc() failed\n");
00348         rc = ERROR_NOT_ENOUGH_MEMORY;
00349         goto cleanup;
00350     }
00351     if (!SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, InstanceId, dwLength, NULL))
00352     {
00353         rc = GetLastError();
00354         DPRINT("SetupDiGetDeviceInstanceIdW() failed with error 0x%lx\n", rc);
00355         goto cleanup;
00356     }
00357 
00358     /* Create device name */
00359     DeviceName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
00360     if (!DeviceName)
00361     {
00362         DPRINT("HeapAlloc() failed\n");
00363         rc = ERROR_NOT_ENOUGH_MEMORY;
00364         goto cleanup;
00365     }
00366     wcscpy(DeviceName, L"\\Device\\");
00367     wcscat(DeviceName, UuidString);
00368 
00369     /* Create export name */
00370     ExportName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\Tcpip_") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
00371     if (!ExportName)
00372     {
00373         DPRINT("HeapAlloc() failed\n");
00374         rc = ERROR_NOT_ENOUGH_MEMORY;
00375         goto cleanup;
00376     }
00377     wcscpy(ExportName, L"\\Device\\Tcpip_");
00378     wcscat(ExportName, UuidString);
00379 
00380     /* Write Tcpip parameters in new service Key */
00381     rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hKey, NULL);
00382     if (rc != ERROR_SUCCESS)
00383     {
00384         DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
00385         goto cleanup;
00386     }
00387     rc = RegCreateKeyExW(hKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hNetworkKey, NULL);
00388     if (rc != ERROR_SUCCESS)
00389     {
00390         DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
00391         goto cleanup;
00392     }
00393     RegCloseKey(hKey);
00394     hKey = NULL;
00395     rc = RegCreateKeyExW(hNetworkKey, L"Parameters\\Tcpip", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL);
00396     if (rc != ERROR_SUCCESS)
00397     {
00398         DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
00399         goto cleanup;
00400     }
00401     RegCloseKey(hNetworkKey);
00402     hNetworkKey = NULL;
00403     rc = RegSetValueExW(hKey, L"DefaultGateway", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR));
00404     if (rc != ERROR_SUCCESS)
00405     {
00406         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00407         goto cleanup;
00408     }
00409     rc = RegSetValueExW(hKey, L"IPAddress", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR));
00410     if (rc != ERROR_SUCCESS)
00411     {
00412         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00413         goto cleanup;
00414     }
00415     rc = RegSetValueExW(hKey, L"SubnetMask", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR));
00416     if (rc != ERROR_SUCCESS)
00417     {
00418         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00419         goto cleanup;
00420     }
00421         dwValue = 1;
00422     rc = RegSetValueExW(hKey, L"EnableDHCP", 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD));
00423     if (rc != ERROR_SUCCESS)
00424     {
00425         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00426         goto cleanup;
00427     }
00428     RegCloseKey(hKey);
00429     hKey = NULL;
00430 
00431     /* Write 'Linkage' key in hardware key */
00432 #if _WIN32_WINNT >= 0x502
00433     hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
00434 #else
00435     hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
00436 #endif
00437     if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
00438         hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
00439     if (hKey == INVALID_HANDLE_VALUE)
00440     {
00441         hKey = NULL;
00442         rc = GetLastError();
00443         DPRINT("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc);
00444         goto cleanup;
00445     }
00446     rc = RegSetValueExW(hKey, L"NetCfgInstanceId", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR));
00447     if (rc != ERROR_SUCCESS)
00448     {
00449         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00450         goto cleanup;
00451     }
00452     rc = RegSetValueExW(hKey, L"Characteristics", 0, REG_DWORD, (const BYTE*)&Characteristics, sizeof(DWORD));
00453     if (rc != ERROR_SUCCESS)
00454     {
00455         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00456         goto cleanup;
00457     }
00458     if (BusType)
00459         rc = RegSetValueExW(hKey, L"BusType", 0, REG_SZ, (const BYTE*)BusType, (wcslen(BusType) + 1) * sizeof(WCHAR));
00460         if (rc != ERROR_SUCCESS)
00461         {
00462             DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00463             goto cleanup;
00464         }
00465     rc = RegCreateKeyExW(hKey, L"Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hLinkageKey, NULL);
00466     if (rc != ERROR_SUCCESS)
00467     {
00468         DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
00469         goto cleanup;
00470     }
00471     rc = RegSetValueExW(hLinkageKey, L"Export", 0, REG_SZ, (const BYTE*)DeviceName, (wcslen(DeviceName) + 1) * sizeof(WCHAR));
00472     if (rc != ERROR_SUCCESS)
00473     {
00474         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00475         goto cleanup;
00476     }
00477     rc = RegSetValueExW(hLinkageKey, L"RootDevice", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR));
00478     if (rc != ERROR_SUCCESS)
00479     {
00480         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00481         goto cleanup;
00482     }
00483     rc = RegSetValueExW(hLinkageKey, L"UpperBind", 0, REG_SZ, (const BYTE*)L"Tcpip", (wcslen(L"Tcpip") + 1) * sizeof(WCHAR));
00484     if (rc != ERROR_SUCCESS)
00485     {
00486         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00487         goto cleanup;
00488     }
00489     RegCloseKey(hKey);
00490     hKey = NULL;
00491 
00492     /* Write connection information in network subkey */
00493     rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hNetworkKey, NULL);
00494     if (rc != ERROR_SUCCESS)
00495     {
00496         DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
00497         goto cleanup;
00498     }
00499     rc = RegCreateKeyExW(hNetworkKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL);
00500     if (rc != ERROR_SUCCESS)
00501     {
00502         DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
00503         goto cleanup;
00504     }
00505     rc = RegCreateKeyExW(hKey, L"Connection", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hConnectionKey, NULL);
00506     RegCloseKey(hKey);
00507     hKey = NULL;
00508     if (rc != ERROR_SUCCESS)
00509     {
00510         DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
00511         goto cleanup;
00512     }
00513     if (!LoadStringW(netcfgx_hInstance, IDS_NET_CONNECT, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
00514     {
00515         wcscpy(szBuffer,L"Network connection");
00516     }
00517     rc = RegSetValueExW(hConnectionKey, L"Name", 0, REG_SZ, (const BYTE*)szBuffer, (wcslen(szBuffer) + 1) * sizeof(WCHAR));
00518     if (rc != ERROR_SUCCESS)
00519     {
00520         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00521         goto cleanup;
00522     }
00523     rc = RegSetValueExW(hConnectionKey, L"PnpInstanceId", 0, REG_SZ, (const BYTE*)InstanceId, (wcslen(InstanceId) + 1) * sizeof(WCHAR));
00524     if (rc != ERROR_SUCCESS)
00525     {
00526         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00527         goto cleanup;
00528     }
00529     dwShowIcon = 1;
00530     rc = RegSetValueExW(hConnectionKey, L"ShowIcon", 0, REG_DWORD, (const BYTE*)&dwShowIcon, sizeof(dwShowIcon));
00531     if (rc != ERROR_SUCCESS)
00532     {
00533         DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
00534         goto cleanup;
00535     }
00536 
00537     /* Write linkage information in Tcpip service */
00538     rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL);
00539     if (rc != ERROR_SUCCESS)
00540     {
00541         DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
00542         goto cleanup;
00543     }
00544     rc = AppendStringToMultiSZ(hKey, L"Bind", DeviceName);
00545     if (rc != ERROR_SUCCESS)
00546     {
00547         DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc);
00548         goto cleanup;
00549     }
00550     rc = AppendStringToMultiSZ(hKey, L"Export", ExportName);
00551     if (rc != ERROR_SUCCESS)
00552     {
00553         DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc);
00554         goto cleanup;
00555     }
00556     rc = AppendStringToMultiSZ(hKey, L"Route", UuidString);
00557     if (rc != ERROR_SUCCESS)
00558     {
00559         DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc);
00560         goto cleanup;
00561     }
00562 
00563     /* Install additionnal services */
00564     rc = InstallAdditionalServices(NULL);
00565     if (rc != ERROR_SUCCESS)
00566     {
00567         DPRINT("InstallAdditionalServices() failed with error 0x%lx\n", rc);
00568         goto cleanup;
00569     }
00570 
00571     rc = ERROR_SUCCESS;
00572 
00573 cleanup:
00574     HeapFree(GetProcessHeap(), 0, InstanceId);
00575     HeapFree(GetProcessHeap(), 0, DeviceName);
00576     HeapFree(GetProcessHeap(), 0, ExportName);
00577     if (hKey != NULL)
00578         RegCloseKey(hKey);
00579     if (hNetworkKey != NULL)
00580         RegCloseKey(hNetworkKey);
00581     if (hLinkageKey != NULL)
00582         RegCloseKey(hLinkageKey);
00583     if (hConnectionKey != NULL)
00584         RegCloseKey(hConnectionKey);
00585     return rc;
00586 }
00587 
00588 static DWORD
00589 InstallNetClient(VOID)
00590 {
00591     DPRINT1("Installation of network clients is not yet supported\n");
00592     return ERROR_GEN_FAILURE;
00593 }
00594 
00595 static DWORD
00596 InstallNetService(VOID)
00597 {
00598     DPRINT1("Installation of network services is not yet supported\n");
00599     return ERROR_GEN_FAILURE;
00600 }
00601 
00602 static DWORD
00603 InstallNetTransport(VOID)
00604 {
00605     DPRINT1("Installation of network protocols is not yet supported\n");
00606     return ERROR_GEN_FAILURE;
00607 }
00608 
00609 DWORD WINAPI
00610 NetClassInstaller(
00611     IN DI_FUNCTION InstallFunction,
00612     IN HDEVINFO DeviceInfoSet,
00613     IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
00614 {
00615     SP_DRVINFO_DATA_W DriverInfoData;
00616     SP_DRVINFO_DETAIL_DATA_W DriverInfoDetail;
00617     WCHAR SectionName[LINE_LEN];
00618     HINF hInf = INVALID_HANDLE_VALUE;
00619     INFCONTEXT InfContext;
00620     UINT ErrorLine;
00621     INT CharacteristicsInt;
00622     DWORD Characteristics;
00623     LPWSTR BusType = NULL;
00624     RPC_STATUS RpcStatus;
00625     UUID Uuid;
00626     LPWSTR UuidRpcString = NULL;
00627     LPWSTR UuidString = NULL;
00628     LONG rc;
00629     DWORD dwLength;
00630 
00631     if (InstallFunction != DIF_INSTALLDEVICE)
00632         return ERROR_DI_DO_DEFAULT;
00633 
00634     DPRINT("%lu %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
00635 
00636     /* Get driver info details */
00637     DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA_W);
00638     if (!SetupDiGetSelectedDriverW(DeviceInfoSet, DeviceInfoData, &DriverInfoData))
00639     {
00640         rc = GetLastError();
00641         DPRINT("SetupDiGetSelectedDriverW() failed with error 0x%lx\n", rc);
00642         goto cleanup;
00643     }
00644     DriverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
00645     if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet, DeviceInfoData, &DriverInfoData, &DriverInfoDetail, sizeof(DriverInfoDetail), NULL)
00646      && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
00647     {
00648         rc = GetLastError();
00649         DPRINT("SetupDiGetDriverInfoDetailW() failed with error 0x%lx\n", rc);
00650         goto cleanup;
00651     }
00652     hInf = SetupOpenInfFileW(DriverInfoDetail.InfFileName, NULL, INF_STYLE_WIN4, &ErrorLine);
00653     if (hInf == INVALID_HANDLE_VALUE)
00654     {
00655         rc = GetLastError();
00656         DPRINT("SetupOpenInfFileW() failed with error 0x%lx\n", rc);
00657         goto cleanup;
00658     }
00659     if (!SetupDiGetActualSectionToInstallW(hInf, DriverInfoDetail.SectionName, SectionName, LINE_LEN, NULL, NULL))
00660     {
00661         rc = GetLastError();
00662         DPRINT("SetupDiGetActualSectionToInstallW() failed with error 0x%lx\n", rc);
00663         goto cleanup;
00664     }
00665 
00666     /* Get Characteristics and BusType (optional) from .inf file */
00667     if (!SetupFindFirstLineW(hInf, SectionName, L"Characteristics", &InfContext))
00668     {
00669         rc = GetLastError();
00670         DPRINT("Unable to find key %S in section %S of file %S (error 0x%lx)\n",
00671             L"Characteristics", SectionName, DriverInfoDetail.InfFileName, rc);
00672         goto cleanup;
00673     }
00674     if (!SetupGetIntField(&InfContext, 1, &CharacteristicsInt))
00675     {
00676         rc = GetLastError();
00677         DPRINT("SetupGetIntField() failed with error 0x%lx\n", rc);
00678         goto cleanup;
00679     }
00680     Characteristics = (DWORD)CharacteristicsInt;
00681     if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET))
00682     {
00683         if (SetupFindFirstLineW(hInf, SectionName, L"BusType", &InfContext))
00684         {
00685             if (!SetupGetStringFieldW(&InfContext, 1, NULL, 0, &dwLength))
00686             {
00687                 rc = GetLastError();
00688                 DPRINT("SetupGetStringFieldW() failed with error 0x%lx\n", rc);
00689                 goto cleanup;
00690             }
00691             BusType = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
00692             if (!BusType)
00693             {
00694                 DPRINT("HeapAlloc() failed\n");
00695                 rc = ERROR_NOT_ENOUGH_MEMORY;
00696                 goto cleanup;
00697             }
00698             if (!SetupGetStringFieldW(&InfContext, 1, BusType, dwLength, NULL))
00699             {
00700                 rc = GetLastError();
00701                 DPRINT("SetupGetStringFieldW() failed with error 0x%lx\n", rc);
00702                 goto cleanup;
00703             }
00704         }
00705     }
00706 
00707     /* Create a new UUID */
00708     RpcStatus = UuidCreate(&Uuid);
00709     if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY)
00710     {
00711         DPRINT("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus);
00712         rc = ERROR_GEN_FAILURE;
00713         goto cleanup;
00714     }
00715     RpcStatus = UuidToStringW(&Uuid, &UuidRpcString);
00716     if (RpcStatus != RPC_S_OK)
00717     {
00718         DPRINT("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus);
00719         rc = ERROR_GEN_FAILURE;
00720         goto cleanup;
00721     }
00722 
00723     /* Add curly braces around Uuid */
00724     UuidString = HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
00725     if (!UuidString)
00726     {
00727         DPRINT("HeapAlloc() failed\n");
00728         rc = ERROR_NOT_ENOUGH_MEMORY;
00729         goto cleanup;
00730     }
00731     wcscpy(UuidString, L"{");
00732     wcscat(UuidString, UuidRpcString);
00733     wcscat(UuidString, L"}");
00734 
00735     if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET))
00736         rc = InstallNetDevice(DeviceInfoSet, DeviceInfoData, UuidString, Characteristics, BusType);
00737     else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETCLIENT))
00738         rc = InstallNetClient();
00739     else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETSERVICE))
00740         rc = InstallNetService();
00741     else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETTRANS))
00742         rc = InstallNetTransport();
00743     else
00744     {
00745         DPRINT("Invalid class guid\n");
00746         rc = ERROR_GEN_FAILURE;
00747     }
00748 
00749 cleanup:
00750     if (hInf != INVALID_HANDLE_VALUE)
00751         SetupCloseInfFile(hInf);
00752     if (UuidRpcString != NULL)
00753         RpcStringFreeW(&UuidRpcString);
00754     HeapFree(GetProcessHeap(), 0, BusType);
00755     HeapFree(GetProcessHeap(), 0, UuidString);
00756 
00757     if (rc == ERROR_SUCCESS)
00758         rc = ERROR_DI_DO_DEFAULT;
00759     DPRINT("Returning 0x%lx\n", rc);
00760     return rc;
00761 }

Generated on Sun May 27 2012 04:25:28 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.