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

adapter.c
Go to the documentation of this file.
00001 #include "rosdhcp.h"
00002 
00003 SOCKET DhcpSocket = INVALID_SOCKET;
00004 static LIST_ENTRY AdapterList;
00005 static WSADATA wsd;
00006 
00007 PCHAR *GetSubkeyNames( PCHAR MainKeyName, PCHAR Append ) {
00008     int i = 0;
00009     DWORD Error;
00010     HKEY MainKey;
00011     PCHAR *Out, OutKeyName;
00012     DWORD CharTotal = 0, AppendLen = 1 + strlen(Append);
00013     DWORD MaxSubKeyLen = 0, MaxSubKeys = 0;
00014 
00015     Error = RegOpenKey( HKEY_LOCAL_MACHINE, MainKeyName, &MainKey );
00016 
00017     if( Error ) return NULL;
00018 
00019     Error = RegQueryInfoKey
00020         ( MainKey,
00021           NULL, NULL, NULL,
00022           &MaxSubKeys, &MaxSubKeyLen,
00023           NULL, NULL, NULL, NULL, NULL, NULL );
00024 
00025     DH_DbgPrint(MID_TRACE,("MaxSubKeys: %d, MaxSubKeyLen %d\n",
00026                            MaxSubKeys, MaxSubKeyLen));
00027 
00028     CharTotal = (sizeof(PCHAR) + MaxSubKeyLen + AppendLen) * (MaxSubKeys + 1);
00029 
00030     DH_DbgPrint(MID_TRACE,("AppendLen: %d, CharTotal: %d\n",
00031                            AppendLen, CharTotal));
00032 
00033     Out = (CHAR**) malloc( CharTotal );
00034     OutKeyName = ((PCHAR)&Out[MaxSubKeys+1]);
00035 
00036     if( !Out ) { RegCloseKey( MainKey ); return NULL; }
00037 
00038     i = 0;
00039     do {
00040         Out[i] = OutKeyName;
00041         Error = RegEnumKey( MainKey, i, OutKeyName, MaxSubKeyLen );
00042         if( !Error ) {
00043             strcat( OutKeyName, Append );
00044             DH_DbgPrint(MID_TRACE,("[%d]: %s\n", i, OutKeyName));
00045             OutKeyName += strlen(OutKeyName) + 1;
00046             i++;
00047         } else Out[i] = 0;
00048     } while( Error == ERROR_SUCCESS );
00049 
00050     RegCloseKey( MainKey );
00051 
00052     return Out;
00053 }
00054 
00055 PCHAR RegReadString( HKEY Root, PCHAR Subkey, PCHAR Value ) {
00056     PCHAR SubOut = NULL;
00057     DWORD SubOutLen = 0, Error = 0;
00058     HKEY  ValueKey = NULL;
00059 
00060     DH_DbgPrint(MID_TRACE,("Looking in %x:%s:%s\n", Root, Subkey, Value ));
00061 
00062     if( Subkey && strlen(Subkey) ) {
00063         if( RegOpenKey( Root, Subkey, &ValueKey ) != ERROR_SUCCESS )
00064             goto regerror;
00065     } else ValueKey = Root;
00066 
00067     DH_DbgPrint(MID_TRACE,("Got Key %x\n", ValueKey));
00068 
00069     if( (Error = RegQueryValueEx( ValueKey, Value, NULL, NULL,
00070                                   (LPBYTE)SubOut, &SubOutLen )) != ERROR_SUCCESS )
00071         goto regerror;
00072 
00073     DH_DbgPrint(MID_TRACE,("Value %s has size %d\n", Value, SubOutLen));
00074 
00075     if( !(SubOut = (CHAR*) malloc(SubOutLen)) )
00076         goto regerror;
00077 
00078     if( (Error = RegQueryValueEx( ValueKey, Value, NULL, NULL,
00079                                   (LPBYTE)SubOut, &SubOutLen )) != ERROR_SUCCESS )
00080         goto regerror;
00081 
00082     DH_DbgPrint(MID_TRACE,("Value %s is %s\n", Value, SubOut));
00083 
00084     goto cleanup;
00085 
00086 regerror:
00087     if( SubOut ) { free( SubOut ); SubOut = NULL; }
00088 cleanup:
00089     if( ValueKey && ValueKey != Root ) {
00090         DH_DbgPrint(MID_TRACE,("Closing key %x\n", ValueKey));
00091         RegCloseKey( ValueKey );
00092     }
00093 
00094     DH_DbgPrint(MID_TRACE,("Returning %x with error %d\n", SubOut, Error));
00095 
00096     return SubOut;
00097 }
00098 
00099 HKEY FindAdapterKey( PDHCP_ADAPTER Adapter ) {
00100     int i = 0;
00101     PCHAR EnumKeyName =
00102         "SYSTEM\\CurrentControlSet\\Control\\Class\\"
00103         "{4D36E972-E325-11CE-BFC1-08002BE10318}";
00104     PCHAR TargetKeyNameStart =
00105         "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
00106     PCHAR TargetKeyName = NULL;
00107     PCHAR *EnumKeysLinkage = GetSubkeyNames( EnumKeyName, "\\Linkage" );
00108     PCHAR *EnumKeysTop     = GetSubkeyNames( EnumKeyName, "" );
00109     PCHAR RootDevice = NULL;
00110     HKEY EnumKey, OutKey = NULL;
00111     DWORD Error = ERROR_SUCCESS;
00112 
00113     if( !EnumKeysLinkage || !EnumKeysTop ) goto cleanup;
00114 
00115     Error = RegOpenKey( HKEY_LOCAL_MACHINE, EnumKeyName, &EnumKey );
00116 
00117     if( Error ) goto cleanup;
00118 
00119     for( i = 0; EnumKeysLinkage[i]; i++ ) {
00120         RootDevice = RegReadString
00121             ( EnumKey, EnumKeysLinkage[i], "RootDevice" );
00122 
00123         if( RootDevice &&
00124             !strcmp( RootDevice, Adapter->DhclientInfo.name ) ) {
00125             TargetKeyName =
00126                 (CHAR*) malloc( strlen( TargetKeyNameStart ) +
00127                         strlen( RootDevice ) + 1);
00128             if( !TargetKeyName ) goto cleanup;
00129             sprintf( TargetKeyName, "%s%s",
00130                      TargetKeyNameStart, RootDevice );
00131             Error = RegCreateKeyExA( HKEY_LOCAL_MACHINE, TargetKeyName, 0, NULL, 0, KEY_READ, NULL, &OutKey, NULL );
00132             break;
00133         } else {
00134             free( RootDevice ); RootDevice = 0;
00135         }
00136     }
00137 
00138 cleanup:
00139     if( RootDevice ) free( RootDevice );
00140     if( EnumKeysLinkage ) free( EnumKeysLinkage );
00141     if( EnumKeysTop ) free( EnumKeysTop );
00142     if( TargetKeyName ) free( TargetKeyName );
00143 
00144     return OutKey;
00145 }
00146 
00147 BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) {
00148     HKEY AdapterKey;
00149     DWORD Error = ERROR_SUCCESS, DhcpEnabled, Length = sizeof(DWORD);
00150 
00151     Adapter->DhclientState.config = &Adapter->DhclientConfig;
00152     strncpy(Adapter->DhclientInfo.name, (char*)Adapter->IfMib.bDescr,
00153             sizeof(Adapter->DhclientInfo.name));
00154 
00155     AdapterKey = FindAdapterKey( Adapter );
00156     if( AdapterKey )
00157     {
00158         Error = RegQueryValueEx(AdapterKey, "EnableDHCP", NULL, NULL, (LPBYTE)&DhcpEnabled, &Length);
00159 
00160         if (Error != ERROR_SUCCESS || Length != sizeof(DWORD))
00161             DhcpEnabled = 1;
00162 
00163         CloseHandle(AdapterKey);
00164     }
00165     else
00166     {
00167         /* DHCP enabled by default */
00168         DhcpEnabled = 1;
00169     }           
00170 
00171     if( !DhcpEnabled ) {
00172         /* Non-automatic case */
00173         DbgPrint("DHCPCSVC: Adapter Name: [%s] (static)\n", Adapter->DhclientInfo.name);
00174 
00175         Adapter->DhclientState.state = S_STATIC;
00176     } else {
00177         /* Automatic case */
00178         DbgPrint("DHCPCSVC: Adapter Name: [%s] (dynamic)\n", Adapter->DhclientInfo.name);
00179 
00180     Adapter->DhclientInfo.client->state = S_INIT;
00181     }
00182 
00183     return TRUE;
00184 }
00185 
00186 void AdapterInit() {
00187     WSAStartup(0x0101,&wsd);
00188 
00189     InitializeListHead( &AdapterList );
00190 }
00191 
00192 int
00193 InterfaceConnected(const MIB_IFROW* IfEntry)
00194 {
00195     if (IfEntry->dwOperStatus == IF_OPER_STATUS_CONNECTED ||
00196         IfEntry->dwOperStatus == IF_OPER_STATUS_OPERATIONAL)
00197         return 1;
00198 
00199     DH_DbgPrint(MID_TRACE,("Interface %d is down\n", IfEntry->dwIndex));
00200     return 0;
00201 }
00202 
00203 BOOL
00204 IsReconnectHackNeeded(PDHCP_ADAPTER Adapter, const MIB_IFROW* IfEntry)
00205 {
00206     struct protocol *proto;
00207     PIP_ADAPTER_INFO AdapterInfo, Orig;
00208     DWORD Size, Ret;
00209     char *ZeroAddress = "0.0.0.0";
00210 
00211     proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
00212 
00213     if (Adapter->DhclientInfo.client->state == S_BOUND && !proto)
00214         return FALSE;
00215 
00216     if (Adapter->DhclientInfo.client->state != S_BOUND &&
00217         Adapter->DhclientInfo.client->state != S_STATIC)
00218         return FALSE;
00219     
00220     ApiUnlock();
00221 
00222     Orig = AdapterInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO));
00223     Size = sizeof(IP_ADAPTER_INFO);
00224     if (!AdapterInfo)
00225     {
00226         ApiLock();
00227         return FALSE;
00228     }
00229 
00230     Ret = GetAdaptersInfo(AdapterInfo, &Size);
00231     if (Ret == ERROR_BUFFER_OVERFLOW)
00232     {
00233         HeapFree(GetProcessHeap(), 0, AdapterInfo);
00234         AdapterInfo = HeapAlloc(GetProcessHeap(), 0, Size);
00235         if (!AdapterInfo)
00236         {
00237             ApiLock();
00238             return FALSE;
00239         }
00240 
00241         if (GetAdaptersInfo(AdapterInfo, &Size) != NO_ERROR)
00242         {
00243             ApiLock();
00244             return FALSE;
00245         }
00246 
00247         Orig = AdapterInfo;
00248         for (; AdapterInfo != NULL; AdapterInfo = AdapterInfo->Next)
00249         {
00250             if (AdapterInfo->Index == IfEntry->dwIndex)
00251                 break;
00252         }
00253 
00254         if (AdapterInfo == NULL)
00255         {
00256             HeapFree(GetProcessHeap(), 0, Orig);
00257             ApiLock();
00258             return FALSE;
00259         }
00260     }
00261     else if (Ret != NO_ERROR)
00262     {
00263         HeapFree(GetProcessHeap(), 0, Orig);
00264         ApiLock();
00265         return FALSE;
00266     }
00267 
00268     if (!strcmp(AdapterInfo->IpAddressList.IpAddress.String, ZeroAddress))
00269     {
00270         HeapFree(GetProcessHeap(), 0, Orig);
00271         ApiLock();
00272         return TRUE;
00273     }
00274     else
00275     {
00276         HeapFree(GetProcessHeap(), 0, Orig);
00277         ApiLock();
00278         return FALSE;
00279     }
00280 }
00281 
00282 /*
00283  * XXX Figure out the way to bind a specific adapter to a socket.
00284  */
00285 DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
00286     PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
00287     DWORD Error, Size = sizeof(MIB_IFTABLE);
00288     PDHCP_ADAPTER Adapter = NULL;
00289     HANDLE AdapterStateChangedEvent = (HANDLE)Context;
00290     struct interface_info *ifi = NULL;
00291     struct protocol *proto;
00292     int i, AdapterCount = 0, Broadcast;
00293 
00294     /* FIXME: Kill this thread when the service is stopped */
00295 
00296     do {
00297        DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
00298 
00299        while( (Error = GetIfTable(Table, &Size, 0 )) ==
00300                ERROR_INSUFFICIENT_BUFFER ) {
00301            DH_DbgPrint(MID_TRACE,("Error %d, New Buffer Size: %d\n", Error, Size));
00302            free( Table );
00303            Table = (PMIB_IFTABLE) malloc( Size );
00304        }
00305 
00306        if( Error != NO_ERROR )
00307        {
00308            /* HACK: We are waiting until TCP/IP starts */
00309            Sleep(2000);
00310            continue;
00311        }
00312 
00313        DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries));
00314 
00315        for( i = Table->dwNumEntries - 1; i >= 0; i-- ) {
00316             DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
00317                                    Table->table[i].dwIndex));
00318 
00319             ApiLock();
00320 
00321             if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen)))
00322             {
00323                 proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
00324 
00325                 /* This is an existing adapter */
00326                 if (InterfaceConnected(&Table->table[i])) {
00327                     /* We're still active so we stay in the list */
00328                     ifi = &Adapter->DhclientInfo;
00329 
00330                     /* This is a hack because IP helper API sucks */
00331                     if (IsReconnectHackNeeded(Adapter, &Table->table[i]))
00332                     {
00333                         /* This handles a disconnect/reconnect */
00334 
00335                         if (proto)
00336                             remove_protocol(proto);
00337                         Adapter->DhclientInfo.client->state = S_INIT;
00338 
00339                         /* These are already invalid since the media state change */
00340                         Adapter->RouterMib.dwForwardNextHop = 0;
00341                         Adapter->NteContext = 0;
00342 
00343                         add_protocol(Adapter->DhclientInfo.name,
00344                                      Adapter->DhclientInfo.rfdesc,
00345                                      got_one, &Adapter->DhclientInfo);
00346                         state_init(&Adapter->DhclientInfo);
00347 
00348                         SetEvent(AdapterStateChangedEvent);
00349                     }
00350 
00351                 } else {
00352                     if (proto)
00353                         remove_protocol(proto);
00354 
00355                     /* We've lost our link so out we go */
00356                     RemoveEntryList(&Adapter->ListEntry);
00357                     free(Adapter);
00358                 }
00359 
00360                 ApiUnlock();
00361 
00362                 continue;
00363             }
00364 
00365             ApiUnlock();
00366 
00367             Adapter = (DHCP_ADAPTER*) calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 );
00368 
00369             if( Adapter && Table->table[i].dwType == MIB_IF_TYPE_ETHERNET && InterfaceConnected(&Table->table[i])) {
00370                 memcpy( &Adapter->IfMib, &Table->table[i],
00371                         sizeof(Adapter->IfMib) );
00372                 Adapter->DhclientInfo.client = &Adapter->DhclientState;
00373                 Adapter->DhclientInfo.rbuf = Adapter->recv_buf;
00374                 Adapter->DhclientInfo.rbuf_max = Table->table[i].dwMtu;
00375                 Adapter->DhclientInfo.rbuf_len =
00376                     Adapter->DhclientInfo.rbuf_offset = 0;
00377                 memcpy(Adapter->DhclientInfo.hw_address.haddr,
00378                        Adapter->IfMib.bPhysAddr,
00379                        Adapter->IfMib.dwPhysAddrLen);
00380                 Adapter->DhclientInfo.hw_address.hlen = Adapter->IfMib.dwPhysAddrLen;
00381 
00382                 /* I'm not sure where else to set this, but
00383                    some DHCP servers won't take a zero.
00384                    We checked the hardware type earlier in
00385                    the if statement. */
00386                 Adapter->DhclientInfo.hw_address.htype = HTYPE_ETHER;
00387 
00388                 if( DhcpSocket == INVALID_SOCKET ) {
00389                     DhcpSocket =
00390                         Adapter->DhclientInfo.rfdesc =
00391                         Adapter->DhclientInfo.wfdesc =
00392                         socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
00393 
00394                     if (DhcpSocket != INVALID_SOCKET) {
00395                         
00396                         /* Allow broadcast on this socket */
00397                         Broadcast = 1;
00398                         setsockopt(DhcpSocket,
00399                                    SOL_SOCKET,
00400                                    SO_BROADCAST,
00401                                    (const char *)&Broadcast,
00402                                    sizeof(Broadcast));
00403                         
00404                         Adapter->ListenAddr.sin_family = AF_INET;
00405                         Adapter->ListenAddr.sin_port = htons(LOCAL_PORT);
00406                         Adapter->BindStatus =
00407                              (bind( Adapter->DhclientInfo.rfdesc,
00408                                     (struct sockaddr *)&Adapter->ListenAddr,
00409                                     sizeof(Adapter->ListenAddr) ) == 0) ?
00410                              0 : WSAGetLastError();
00411                     } else {
00412                         error("socket() failed: %d\n", WSAGetLastError());
00413                     }
00414                 } else {
00415                     Adapter->DhclientInfo.rfdesc =
00416                         Adapter->DhclientInfo.wfdesc = DhcpSocket;
00417                 }
00418 
00419                 Adapter->DhclientConfig.timeout = DHCP_PANIC_TIMEOUT;
00420                 Adapter->DhclientConfig.initial_interval = DHCP_DISCOVER_INTERVAL;
00421                 Adapter->DhclientConfig.retry_interval = DHCP_DISCOVER_INTERVAL;
00422                 Adapter->DhclientConfig.select_interval = 1;
00423                 Adapter->DhclientConfig.reboot_timeout = DHCP_REBOOT_TIMEOUT;
00424                 Adapter->DhclientConfig.backoff_cutoff = DHCP_BACKOFF_MAX;
00425                 Adapter->DhclientState.interval =
00426                     Adapter->DhclientConfig.retry_interval;
00427 
00428                 if( PrepareAdapterForService( Adapter ) ) {
00429                     Adapter->DhclientInfo.next = ifi;
00430                     ifi = &Adapter->DhclientInfo;
00431 
00432                     read_client_conf(&Adapter->DhclientInfo);
00433 
00434                     if (Adapter->DhclientInfo.client->state == S_INIT)
00435                     {
00436                         add_protocol(Adapter->DhclientInfo.name,
00437                                      Adapter->DhclientInfo.rfdesc,
00438                                      got_one, &Adapter->DhclientInfo);
00439 
00440                         state_init(&Adapter->DhclientInfo);
00441                     }
00442 
00443                     ApiLock();
00444                     InsertTailList( &AdapterList, &Adapter->ListEntry );
00445                     AdapterCount++;
00446                     SetEvent(AdapterStateChangedEvent);
00447                     ApiUnlock();
00448                 } else { free( Adapter ); Adapter = 0; }
00449             } else { free( Adapter ); Adapter = 0; }
00450 
00451             if( !Adapter )
00452                 DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n",
00453                                        Table->table[i].dwIndex));
00454         }
00455 #if 0
00456         Error = NotifyAddrChange(NULL, NULL);
00457         if (Error != NO_ERROR)
00458             break;
00459 #else
00460         Sleep(3000);
00461 #endif
00462     } while (TRUE);
00463 
00464     DbgPrint("DHCPCSVC: Adapter discovery thread is terminating! (Error: %d)\n", Error);
00465 
00466     if( Table ) free( Table );
00467     return Error;
00468 }
00469 
00470 HANDLE StartAdapterDiscovery(VOID) {
00471     HANDLE ThreadHandle, EventHandle;
00472 
00473     EventHandle = CreateEvent(NULL,
00474                               FALSE,
00475                               FALSE,
00476                               NULL);
00477 
00478     ThreadHandle = CreateThread(NULL,
00479                                 0,
00480                                 AdapterDiscoveryThread,
00481                                 (LPVOID)EventHandle,
00482                                 0,
00483                                 NULL);
00484 
00485     if (ThreadHandle == NULL)
00486         return NULL;
00487 
00488     CloseHandle(ThreadHandle);
00489 
00490     return EventHandle;
00491 }
00492 
00493 void AdapterStop() {
00494     PLIST_ENTRY ListEntry;
00495     PDHCP_ADAPTER Adapter;
00496     ApiLock();
00497     while( !IsListEmpty( &AdapterList ) ) {
00498         ListEntry = (PLIST_ENTRY)RemoveHeadList( &AdapterList );
00499         Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
00500         free( Adapter );
00501     }
00502     ApiUnlock();
00503     WSACleanup();
00504 }
00505 
00506 PDHCP_ADAPTER AdapterFindIndex( unsigned int indx ) {
00507     PDHCP_ADAPTER Adapter;
00508     PLIST_ENTRY ListEntry;
00509 
00510     for( ListEntry = AdapterList.Flink;
00511          ListEntry != &AdapterList;
00512          ListEntry = ListEntry->Flink ) {
00513         Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
00514         if( Adapter->IfMib.dwIndex == indx ) return Adapter;
00515     }
00516 
00517     return NULL;
00518 }
00519 
00520 PDHCP_ADAPTER AdapterFindName( const WCHAR *name ) {
00521     PDHCP_ADAPTER Adapter;
00522     PLIST_ENTRY ListEntry;
00523 
00524     for( ListEntry = AdapterList.Flink;
00525          ListEntry != &AdapterList;
00526          ListEntry = ListEntry->Flink ) {
00527         Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
00528         if( !wcsicmp( Adapter->IfMib.wszName, name ) ) return Adapter;
00529     }
00530 
00531     return NULL;
00532 }
00533 
00534 PDHCP_ADAPTER AdapterFindInfo( struct interface_info *ip ) {
00535     PDHCP_ADAPTER Adapter;
00536     PLIST_ENTRY ListEntry;
00537 
00538     for( ListEntry = AdapterList.Flink;
00539          ListEntry != &AdapterList;
00540          ListEntry = ListEntry->Flink ) {
00541         Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
00542         if( ip == &Adapter->DhclientInfo ) return Adapter;
00543     }
00544 
00545     return NULL;
00546 }
00547 
00548 PDHCP_ADAPTER AdapterFindByHardwareAddress( u_int8_t haddr[16], u_int8_t hlen ) {
00549     PDHCP_ADAPTER Adapter;
00550     PLIST_ENTRY ListEntry;
00551 
00552     for(ListEntry = AdapterList.Flink;
00553         ListEntry != &AdapterList;
00554         ListEntry = ListEntry->Flink) {
00555        Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
00556        if (Adapter->DhclientInfo.hw_address.hlen == hlen &&
00557            !memcmp(Adapter->DhclientInfo.hw_address.haddr,
00558                   haddr,
00559                   hlen)) return Adapter;
00560     }
00561 
00562     return NULL;
00563 }
00564 
00565 PDHCP_ADAPTER AdapterGetFirst() {
00566     if( IsListEmpty( &AdapterList ) ) return NULL; else {
00567         return CONTAINING_RECORD
00568             ( AdapterList.Flink, DHCP_ADAPTER, ListEntry );
00569     }
00570 }
00571 
00572 PDHCP_ADAPTER AdapterGetNext( PDHCP_ADAPTER This )
00573 {
00574     if( This->ListEntry.Flink == &AdapterList ) return NULL;
00575     return CONTAINING_RECORD
00576         ( This->ListEntry.Flink, DHCP_ADAPTER, ListEntry );
00577 }
00578 
00579 void if_register_send(struct interface_info *ip) {
00580 
00581 }
00582 
00583 void if_register_receive(struct interface_info *ip) {
00584 }

Generated on Sun May 27 2012 04:21:13 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.