//---------------------------------------------------------------------------- // // Copyright (c) 1997-1999 Microsoft Corporation // All rights reserved. // // File Name: // init.c // // Description: This file contains all of the functions that handle // initialization of the App. // //---------------------------------------------------------------------------- #include "pch.h" #include "allres.h" // // Net support // static VOID LoadStringsAndDefaultsForNetworkComponents( VOID); // // Timezone support // static BOOL ReadZoneData(TIME_ZONE_ENTRY* zone, HKEY key); static TIME_ZONE_LIST *BuildTimeZoneList(VOID); // // Regional Settings support // static VOID BuildLanguageLists( VOID ); extern BOOL GetCommaDelimitedEntry( OUT TCHAR szString[], IN OUT TCHAR **pBuffer ); //---------------------------------------------------------------------------- // // Function: InitTheWizard // // Purpose: Performs one time initialization for the App. This function // is to be called once and only once each time the App is run. // // Arguments: VOID // // Returns: VOID // //---------------------------------------------------------------------------- VOID InitTheWizard(VOID) { // // Save the dir the program was launched from // GetCurrentDirectory( MAX_PATH + 1, FixedGlobals.szSavePath ); // // Have to load the strings for the titles on the networking property // sheets here because the title is displayed before the WM_INITDIALOG // message is sent // g_StrTcpipTitle = MyLoadString( IDS_TCPIP_TITLE ); g_StrAdvancedTcpipSettings = MyLoadString( IDS_ADVANCED_TCPIP_SETTINGS ); g_StrIpxProtocolTitle = MyLoadString( IDS_IPX_PROTOCOL_TITLE ); g_StrAppletalkProtocolTitle = MyLoadString( IDS_APPLETALK_TITLE ); g_StrMsClientTitle = MyLoadString( IDS_MSCLIENT_TITLE ); // // Initialize network settings // NetSettings.NetworkAdapterHead = malloc( sizeof( NETWORK_ADAPTER_NODE ) ); NetSettings.pCurrentAdapter = NetSettings.NetworkAdapterHead; CreateListWithDefaults( NetSettings.pCurrentAdapter ); // // Initialize the number of network card variables // NetSettings.iNumberOfNetworkCards = 1; NetSettings.iCurrentNetworkCard = 1; NetSettings.NetworkAdapterHead->next = NULL; LoadStringsAndDefaultsForNetworkComponents(); // // Build the list of timezones // FixedGlobals.TimeZoneList = BuildTimeZoneList(); // // Build the list of Language Groups and Locales // BuildLanguageLists(); } //-------------------------------------------------------------------------- // // Support for loading timezone info from the registry // //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // // Function: ReadZoneData // // Purpose: Fills in a TIME_ZONE_ENTRY. // // Returns: BOOL // //-------------------------------------------------------------------------- static BOOL ReadZoneData(TIME_ZONE_ENTRY* zone, HKEY key) { DWORD len; // // Get the display name // len = sizeof(zone->DisplayName); if ( RegQueryValueEx(key, REGVAL_TZ_DISPLAY, 0, NULL, (LPBYTE)zone->DisplayName, &len) != ERROR_SUCCESS ) { return (FALSE); } // // Get the StandardName // len = sizeof(zone->StdName); if ( RegQueryValueEx(key, REGVAL_TZ_STDNAME, 0, NULL, (LPBYTE)zone->StdName, &len) != ERROR_SUCCESS ) { return (FALSE); } // // Get the number associatted with this timezone // zone->Index = 0; len = sizeof(zone->Index); if ( RegQueryValueEx(key, REGVAL_TZ_INDEX, 0, NULL, (LPBYTE)&zone->Index, &len) != ERROR_SUCCESS ) { return (FALSE); } return (TRUE); } //---------------------------------------------------------------------------- // // Function: InsertZone // // Purpose: Inserts a timezone entry into the timezone list maintains a sorted // order. // // Arguments: IN OUT TIME_ZONE_LIST *TzList - time zone list the entry is to // be inserted to // IN TIME_ZONE_ENTRY NewTimeZoneEntry - the timezone entry to be // inserted // IN INT iNumberOfZonesInserted - number of timezone entries // already inserted in to the TzList // // Returns: VOID // //---------------------------------------------------------------------------- VOID InsertZone( IN OUT TIME_ZONE_LIST *TzList, IN TIME_ZONE_ENTRY NewTimeZoneEntry, IN INT iNumberOfZonesInserted ) { INT i = 0; INT j; while( i < iNumberOfZonesInserted ) { if( TzList->TimeZones[i].Index < NewTimeZoneEntry.Index ) { i++; } else { break; // we found the insertion point } } // // Slide all the entries up 1 to make room for the new entry // for( j = iNumberOfZonesInserted - 1; j >= i; j-- ) { lstrcpyn( TzList->TimeZones[j+1].DisplayName, TzList->TimeZones[j].DisplayName, AS(TzList->TimeZones[j+1].DisplayName) ); lstrcpyn( TzList->TimeZones[j+1].StdName, TzList->TimeZones[j].StdName, AS(TzList->TimeZones[j+1].StdName) ); TzList->TimeZones[j+1].Index = TzList->TimeZones[j].Index; } // // Add the new entry to the array // lstrcpyn( TzList->TimeZones[i].DisplayName, NewTimeZoneEntry.DisplayName, AS(TzList->TimeZones[i].DisplayName) ); lstrcpyn( TzList->TimeZones[i].StdName, NewTimeZoneEntry.StdName, AS(TzList->TimeZones[i].StdName) ); TzList->TimeZones[i].Index = NewTimeZoneEntry.Index; } //-------------------------------------------------------------------------- // // Function: BuildTimeZoneList // // Purpose: Mallocs and fills in a TIME_ZONE_LIST which has an array of // timezone data. // // Returns: BOOL - success // //-------------------------------------------------------------------------- static TIME_ZONE_LIST *BuildTimeZoneList(VOID) { HKEY TimeZoneRootKey = NULL; WCHAR SubKeyName[TZNAME_SIZE]; HKEY SubKey = NULL; int i; INT iNumberOfZonesInserted; TIME_ZONE_ENTRY TempTimeZoneEntry; DWORD NumTimeZones = 0; TIME_ZONE_LIST *TzList; TCHAR *szTempString; // // Open the root of the timezone list in the registry. // if (RegOpenKey( HKEY_LOCAL_MACHINE, REGKEY_TIMEZONES, &TimeZoneRootKey ) != ERROR_SUCCESS) { return NULL; } // // Find out how many sub-keys (timezones) there are. // RegQueryInfoKey(TimeZoneRootKey, NULL, NULL, NULL, &NumTimeZones, NULL, NULL, NULL, NULL, NULL, NULL, NULL); // // We need to fudge the number of TIME_ZONE_ENTRIES because we add // 2 special ones "Set Same As Server" and "Do Not Specify". // NumTimeZones += 2; // // Malloc the memory we need // if ( (TzList = malloc(sizeof(TIME_ZONE_LIST))) == NULL ) { RegCloseKey(TimeZoneRootKey); return NULL; } TzList->NumEntries = NumTimeZones; TzList->TimeZones = malloc(NumTimeZones * sizeof(TIME_ZONE_ENTRY)); if ( TzList->TimeZones == NULL ) { RegCloseKey(TimeZoneRootKey); free(TzList); return NULL; } // // Enumerate the sub-keys under the timezone root. Each key at this // level is the standard name of a timezone. Under that key are // the values we care about. Call ReadZoneData() for each one to // retrieve the display name and index. // i = 0; iNumberOfZonesInserted = 0; while ( RegEnumKey(TimeZoneRootKey, i, SubKeyName, TZNAME_SIZE) == ERROR_SUCCESS) { if (RegOpenKey(TimeZoneRootKey, SubKeyName, &SubKey) == ERROR_SUCCESS) { if ( ReadZoneData( &TempTimeZoneEntry, SubKey) ) { InsertZone( TzList, TempTimeZoneEntry, iNumberOfZonesInserted ); iNumberOfZonesInserted++; } } RegCloseKey(SubKey); i++; } RegCloseKey(TimeZoneRootKey); // // Put the 2 special entries in at the end of the list // szTempString = MyLoadString(IDS_DONTSPECIFYSETTING); if (szTempString == NULL) { free(TzList->TimeZones); free(TzList); return NULL; } lstrcpyn(TzList->TimeZones[NumTimeZones-2].DisplayName, szTempString, AS(TzList->TimeZones[NumTimeZones-2].DisplayName)); lstrcpyn(TzList->TimeZones[NumTimeZones-2].StdName, _T(""), AS(TzList->TimeZones[NumTimeZones-2].StdName)); TzList->TimeZones[NumTimeZones-2].Index = TZ_IDX_DONOTSPECIFY; free( szTempString ); szTempString = MyLoadString(IDS_SET_SAME_AS_SERVER); if (szTempString == NULL) { free(TzList->TimeZones); free(TzList); return NULL; } lstrcpyn(TzList->TimeZones[NumTimeZones-1].DisplayName, szTempString, AS(TzList->TimeZones[NumTimeZones-1].DisplayName)); lstrcpyn(TzList->TimeZones[NumTimeZones-1].StdName, _T(""), AS(TzList->TimeZones[NumTimeZones-1].StdName)); TzList->TimeZones[NumTimeZones-1].Index = TZ_IDX_SETSAMEASSERVER; free(szTempString); // // Add in the 2 special strings // iNumberOfZonesInserted = iNumberOfZonesInserted + 2; if ( iNumberOfZonesInserted != (int) NumTimeZones ) { free(TzList->TimeZones); free(TzList); return NULL; } return TzList; } //---------------------------------------------------------------------------- // // Function: ReadAllFilesUnderSection // // Purpose: // // Arguments: // // Returns: VOID // //---------------------------------------------------------------------------- static VOID ReadAllFilesUnderSection( IN HINF hInterntlInf, IN LPCTSTR pszSubSectionName, OUT NAMELIST *CurrentNameList ) { TCHAR szLangFileName[MAX_PATH + 1]; INFCONTEXT LangInfContext = { 0 }; INT iRet; AssertMsg( hInterntlInf != INVALID_HANDLE_VALUE, "Bad handle" ); AssertMsg( GetNameListSize( CurrentNameList ) < 100, "Too many entries" ); iRet = SetupFindFirstLine( hInterntlInf, pszSubSectionName, NULL, &LangInfContext ); if( iRet == 0 ) { // // If the subsection can't be found, just return. When this happens, it // mostly likely means there are no files under this subsection. // return; } do { szLangFileName[0] = _T('\0'); iRet = SetupGetStringField( &LangInfContext, 1, szLangFileName, MAX_PATH, NULL ); if( iRet == 0 ) { // // If a file cannot be obtained, move on to the next one. // continue; } if( szLangFileName[0] != _T('\0') ) { AddNameToNameListNoDuplicates( CurrentNameList, szLangFileName ); } } // move to the next line of the .inf file while( SetupFindNextLine( &LangInfContext, &LangInfContext ) ); } //---------------------------------------------------------------------------- // // Function: BuildAdditionalLanguageList // // Purpose: Populate the LangGroupAdditionalFiles array // // LangGroupAdditionalFiles is a dynamically allocated array of Namelists // that contain the extra files in the intl.inf that need to be copied for // a language group in addition to its sub-directory. // // Arguments: // // Returns: VOID // //---------------------------------------------------------------------------- static VOID BuildAdditionalLanguageList( IN HINF hInterntlInf, IN const INT iLangGroupCount ) { INT i; INT j; INT iRetVal; INT iSubSectionEntries; TCHAR szBuffer[MAX_INILINE_LEN]; TCHAR szIniBuffer[MAX_INILINE_LEN]; TCHAR szSectionName[MAX_INILINE_LEN]; TCHAR szIntlInf[MAX_PATH + 1]; TCHAR *pszSubSectionName; TCHAR *pszIniBuffer; NAMELIST SubSectionList = { 0 }; HRESULT hrCat; AssertMsg( hInterntlInf != INVALID_HANDLE_VALUE, "Bad handle" ); iRetVal = GetWindowsDirectory( szIntlInf, MAX_PATH ); if( iRetVal == 0 || iRetVal > MAX_PATH ) { return; } hrCat=StringCchCat( szIntlInf, AS(szIntlInf), _T("\\inf\\intl.inf") ); FixedGlobals.LangGroupAdditionalFiles = malloc( sizeof(NAMELIST) * iLangGroupCount ); if (FixedGlobals.LangGroupAdditionalFiles == NULL) { TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); } ZeroMemory( FixedGlobals.LangGroupAdditionalFiles, sizeof(NAMELIST) * iLangGroupCount ); for( i = 1; i <= iLangGroupCount; i++ ) { lstrcpyn( szSectionName, _T("LG_INSTALL_"), AS(szSectionName) ); hrCat=StringCchCat( szSectionName, AS(szSectionName), _itot( i, szBuffer, 10 ) ); GetPrivateProfileString( szSectionName, _T("CopyFiles"), _T(""), szIniBuffer, StrBuffSize(szIniBuffer), szIntlInf ); // // Loop grabbing each of the sub-section names and inserting them into // the namelist // pszIniBuffer = szIniBuffer; while( GetCommaDelimitedEntry( szBuffer, &pszIniBuffer ) ) { AddNameToNameListNoDuplicates( &SubSectionList, szBuffer ); } iSubSectionEntries = GetNameListSize( &SubSectionList ); for( j = 0; j < iSubSectionEntries; j++ ) { pszSubSectionName = GetNameListName( &SubSectionList, j ); ReadAllFilesUnderSection( hInterntlInf, pszSubSectionName, &( FixedGlobals.LangGroupAdditionalFiles[i - 1] ) ); } ResetNameList( &SubSectionList ); } } //---------------------------------------------------------------------------- // // Function: BuildLanguageLists // // Purpose: Mallocs and fills in a LANGUAGEGROUP_LIST and a LANGUAGELOCALE_LIST // which are lists that that maintain language settings read from intl.inf // // Adjusts the global variables FixedGlobals.LanguageGroupList and // FixedGlobals.LanguageLocaleList to point to their respective lists // // Arguments: VOID // // Returns: VOID // //---------------------------------------------------------------------------- static VOID BuildLanguageLists( VOID ) { #define INTERNATIONAL_INF _T("intl.inf") #define LANGUAGE_GROUP_NAME 1 #define LANGUAGE_GROUP_ID 3 #define LANGUAGE_LOCALE_NAME 1 #define LANGUAGE_LOCALE_ID 0 #define KEYBOARD_LAYOUT 5 HINF hInterntlInf = NULL; INFCONTEXT LangInfContext = { 0 }; INFCONTEXT LocaleInfContext = { 0 }; TCHAR szBuffer[MAX_STRING_LEN] = _T(""); INT iLangGroupCount = 0; LANGUAGEGROUP_LIST *LangNode = NULL; LANGUAGEGROUP_LIST *CurrentLangNode = NULL; LANGUAGELOCALE_LIST *LocaleNode = NULL; LANGUAGELOCALE_LIST *CurrentLocaleNode = NULL; // // Read in from the file intl.inf and build the language list // hInterntlInf = SetupOpenInfFile( INTERNATIONAL_INF, NULL, INF_STYLE_WIN4, NULL ); if( hInterntlInf == INVALID_HANDLE_VALUE ) { // ISSUE-2002/02/28-stelo - should allow browse for file here? } LangInfContext.Inf = hInterntlInf; LangInfContext.CurrentInf = hInterntlInf; LocaleInfContext.Inf = hInterntlInf; LocaleInfContext.CurrentInf = hInterntlInf; // // For each Language Group, add its corresponding data to the language group list // SetupFindFirstLine( hInterntlInf, _T("LanguageGroups"), NULL, &LangInfContext ); do { LangNode = malloc( sizeof( LANGUAGEGROUP_LIST ) ); if (LangNode == NULL) { TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); } else { LangNode->next = NULL; SetupGetStringField( &LangInfContext, 0, LangNode->szLanguageGroupId, MAX_STRING_LEN, NULL ); SetupGetStringField( &LangInfContext, 1, LangNode->szLanguageGroupName, MAX_STRING_LEN, NULL ); SetupGetStringField( &LangInfContext, 2, LangNode->szLangFilePath, MAX_STRING_LEN, NULL ); } // See if the LanguageGroupList has been assigned yet. It will not be if // it is NULL. If currentLangNode is NULL, then resetart LanguageGroupList // at the new LangNode as well. if( (FixedGlobals.LanguageGroupList == NULL) || (CurrentLangNode == NULL)) { FixedGlobals.LanguageGroupList = LangNode; CurrentLangNode = LangNode; } else { CurrentLangNode->next = LangNode; CurrentLangNode = CurrentLangNode->next; } iLangGroupCount++; } // move to the next line of the .inf file while( SetupFindNextLine( &LangInfContext, &LangInfContext ) ); // // For each locale, add its corresponding data to the language locale list // SetupFindFirstLine( hInterntlInf, _T("Locales"), NULL, &LocaleInfContext ); do { LocaleNode = malloc( sizeof( LANGUAGELOCALE_LIST ) ); if (LocaleNode == NULL) { TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); } else { LocaleNode->next = NULL; // // Get the Language Locale Name // SetupGetStringField( &LocaleInfContext, LANGUAGE_LOCALE_NAME, LocaleNode->szLanguageLocaleName, MAX_STRING_LEN, NULL ); // // Get the Language Locale ID // SetupGetStringField( &LocaleInfContext, LANGUAGE_LOCALE_ID, LocaleNode->szLanguageLocaleId, MAX_STRING_LEN, NULL ); // // Get the Keyboard Layout // SetupGetStringField( &LocaleInfContext, KEYBOARD_LAYOUT, LocaleNode->szKeyboardLayout, MAX_STRING_LEN, NULL ); // // Get the Language Group ID // SetupGetStringField( &LocaleInfContext, LANGUAGE_GROUP_ID, szBuffer, MAX_STRING_LEN, NULL ); // // Find the Language Group string that goes with the Language Group ID // for( CurrentLangNode = FixedGlobals.LanguageGroupList; CurrentLangNode != NULL; CurrentLangNode = CurrentLangNode->next ) { if( lstrcmp( CurrentLangNode->szLanguageGroupId, szBuffer ) == 0 ) { LocaleNode->pLanguageGroup = CurrentLangNode; break; // found what we were looking for so break } } } // // Add the new node into the linked list // // See if the LanguageLocaleList has been assigned yet. It will not be if // it is NULL. If currentLocaleNode is NULL, then resetart LanguageLocaleList // at the new LocaleNode as well. if( (FixedGlobals.LanguageLocaleList == NULL) || (CurrentLocaleNode == NULL)) { FixedGlobals.LanguageLocaleList = LocaleNode; CurrentLocaleNode = LocaleNode; } else { CurrentLocaleNode->next = LocaleNode; CurrentLocaleNode = CurrentLocaleNode->next; } } // move to the next line of the .inf file while( SetupFindNextLine( &LocaleInfContext, &LocaleInfContext ) ); // // Set the default locale // SetupFindFirstLine( hInterntlInf, _T("DefaultValues"), NULL, &LocaleInfContext ); SetupGetStringField( &LocaleInfContext, 1, g_szDefaultLocale, MAX_LANGUAGE_LEN, NULL ); BuildAdditionalLanguageList( hInterntlInf, iLangGroupCount ); SetupCloseInfFile( hInterntlInf ); } //---------------------------------------------------------------------------- // // Function: LoadStringsAndDefaultsForNetworkComponents // // Purpose: // // Arguments: VOID // // Returns: VOID // //---------------------------------------------------------------------------- static VOID LoadStringsAndDefaultsForNetworkComponents( VOID ) { // // Load strings from resources and setup initial values for global // network components list // NETWORK_COMPONENT *pNetComponent; pNetComponent = malloc( sizeof( NETWORK_COMPONENT ) ); if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); NetSettings.NetComponentsList = pNetComponent; pNetComponent->StrComponentName = MyLoadString( IDS_CLIENT_FOR_MS_NETWORKS ); pNetComponent->StrComponentDescription = MyLoadString( IDS_CLIENT_FOR_MS_NETWORKS_DESC ); pNetComponent->iPosition = MS_CLIENT_POSITION; pNetComponent->ComponentType = CLIENT; pNetComponent->bHasPropertiesTab = TRUE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = TRUE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_CLIENT_FOR_NETWARE ); pNetComponent->StrComponentDescription = MyLoadString( IDS_CLIENT_FOR_NETWARE_DESC ); pNetComponent->iPosition = NETWARE_CLIENT_POSITION; pNetComponent->ComponentType = CLIENT; pNetComponent->bHasPropertiesTab = TRUE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = TRUE; pNetComponent->dwPlatforms = 0x0 | WORKSTATION_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_FILE_AND_PRINT_SHARING ); pNetComponent->StrComponentDescription = MyLoadString( IDS_FILE_AND_PRINT_SHARING_DESC ); pNetComponent->iPosition = FILE_AND_PRINT_SHARING_POSITION; pNetComponent->ComponentType = SERVICE; pNetComponent->bHasPropertiesTab = FALSE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_PACKET_SCHEDULING_DRIVER ); pNetComponent->StrComponentDescription = MyLoadString( IDS_PACKET_SCHEDULING_DRIVER_DESC ); pNetComponent->iPosition = PACKET_SCHEDULING_POSITION; pNetComponent->ComponentType = SERVICE; pNetComponent->bHasPropertiesTab = FALSE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_APPLETALK_PROTOCOL ); pNetComponent->StrComponentDescription = MyLoadString( IDS_APPLETALK_PROTOCOL_DESC ); pNetComponent->iPosition = APPLETALK_POSITION; pNetComponent->ComponentType = PROTOCOL; pNetComponent->bHasPropertiesTab = FALSE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_TCPIP ); pNetComponent->StrComponentDescription = MyLoadString( IDS_TCPIP_DESC ); pNetComponent->iPosition = TCPIP_POSITION; pNetComponent->ComponentType = PROTOCOL; pNetComponent->bHasPropertiesTab = TRUE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_NETWORK_MONITOR_AGENT ); pNetComponent->StrComponentDescription = MyLoadString( IDS_NETWORK_MONITOR_AGENT_DESC ); pNetComponent->iPosition = NETWORK_MONITOR_AGENT_POSITION; pNetComponent->ComponentType = PROTOCOL; pNetComponent->bHasPropertiesTab = FALSE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_IPX_PROTOCOL ); pNetComponent->StrComponentDescription = MyLoadString( IDS_IPX_PROTOCOL_DESC ); pNetComponent->iPosition = IPX_POSITION; pNetComponent->ComponentType = PROTOCOL; pNetComponent->bHasPropertiesTab = TRUE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_DLC_PROTOCOL ); pNetComponent->StrComponentDescription = MyLoadString( IDS_DLC_PROTOCOL_DESC ); pNetComponent->iPosition = DLC_POSITION; pNetComponent->ComponentType = PROTOCOL; pNetComponent->bHasPropertiesTab = FALSE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_NETBEUI_PROTOCOL ); pNetComponent->StrComponentDescription = MyLoadString( IDS_NETBEUI_PROTOCOL_DESC ); pNetComponent->iPosition = NETBEUI_POSITION; pNetComponent->ComponentType = PROTOCOL; pNetComponent->bHasPropertiesTab = FALSE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_SAP_AGENT ); pNetComponent->StrComponentDescription = MyLoadString( IDS_SAP_AGENT_DESC ); pNetComponent->iPosition = SAP_AGENT_POSITION; pNetComponent->ComponentType = SERVICE; pNetComponent->bHasPropertiesTab = FALSE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = FALSE; pNetComponent->dwPlatforms = 0x0 | PERSONAL_INSTALL | WORKSTATION_INSTALL | SERVER_INSTALL; pNetComponent->next = malloc( sizeof( NETWORK_COMPONENT ) ); pNetComponent = pNetComponent->next; if (pNetComponent == NULL) TerminateTheWizard(IDS_ERROR_OUTOFMEMORY); pNetComponent->StrComponentName = MyLoadString( IDS_GATEWAY_FOR_NETWARE ); pNetComponent->StrComponentDescription = MyLoadString( IDS_GATEWAY_FOR_NETWARE_DESC ); pNetComponent->iPosition = GATEWAY_FOR_NETWARE_POSITION; pNetComponent->ComponentType = CLIENT; pNetComponent->bHasPropertiesTab = TRUE; pNetComponent->bInstalled = FALSE; pNetComponent->bSysprepSupport = TRUE; pNetComponent->dwPlatforms = 0x0 | SERVER_INSTALL; pNetComponent->next = NULL; // terminate the list NetSettings.NumberOfNetComponents = 11; }