#include <windows.h>
#include <stdio.h>
#include <sys/stat.h>

/* modified with suggestions from Kevin Dunlap so we only pick out netcards bound to tcpip */
/* modified 12/96 by Leon and Larry to handle mutlipe ip's and multiple bindings
   after *much* heated discussion :) */


/* this routine first checks if the same mstcpnetkey matches under
   enum\net ... likely as this is all the old routine checked.. if the bindings
   match it returns it.. otherwise it enumerates through all keys looking for
   one with matching mstcp\xxxx binding numbers where xxxx=the passed in mstcpnetkey */
   
BOOL  find_matching_netkey(mstcpnetkey,netkey)
       char *mstcpnetkey;
       char *netkey;
{

 char checkkey[50];
 DWORD sizeofcheckkey = 50;
 char valuekey[50];
 DWORD sizeofvaluekey = 50;
 char adapkey[50];
 DWORD sizeofadapkey = 50;
 char localnetkey[50];
 DWORD sizeoflocalnetkey = 50;
 HKEY bk, lnk;                      /* registry key handle */
 BOOL bSuccess;
 int enumcount = 0;
 DWORD vtype;
 DWORD valueresultsize = 50;
 char valueresult[50];



 strcpy(checkkey,"ENUM\\Root\\Net\\");
 strcat(checkkey,mstcpnetkey);
 strcat(checkkey,"\\BINDINGS");

 strcpy(valuekey,"MSTCP\\");
 strcat(valuekey,mstcpnetkey);

 printf("Opening [%s] to do a Quick-Check for %s.\n",checkkey,valuekey);	
 bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,checkkey,&bk);
 if(bSuccess != ERROR_SUCCESS) 
   {
      /* comment out later */
      printf("Quick-Check was unsuccesful. (not a problem!)\n");
   }
  else // opened ok now try the regqueryvalue
  {
    valueresultsize = 50;
    bSuccess = RegQueryValueEx(bk, (LPSTR)valuekey, (LPDWORD)NULL, 
               (LPDWORD)&vtype, (LPBYTE)valueresult, (LPDWORD)&valueresultsize);

    if(bSuccess == ERROR_SUCCESS)
      {
        RegCloseKey(bk);
        printf("Found immediate match for MSTCP key! [%s]\n",valuekey);
        strcpy(netkey,mstcpnetkey);
        return TRUE;
      }
     else
     {
       RegCloseKey(bk); 
       printf("Cannot get the query value!\n",bSuccess);
     }
  }

   /* ok if we get here we did not find an immediate match so now that
      means we must go through all the enum\net entries and then binding
      entries on each in turn */
   /* the above immediate match check was a shortcut for efficiency reasons */

 enumcount = 0;
 strcpy(localnetkey,"ENUM\\Root\\Net\\");
 bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,localnetkey,&lnk);
 if(bSuccess != ERROR_SUCCESS) 
    {
        printf("Can not get Dial-UP info from registry.\n");
        strcpy(netkey,"dummy");
        return FALSE;
    }
 else while (1) //  adapters loop
	{
	     sizeofadapkey = 50;
	     bSuccess = RegEnumKey(lnk, (DWORD)enumcount, (LPTSTR)adapkey, sizeofadapkey);
	     if(bSuccess == ERROR_NO_MORE_ITEMS)
		  {
		   printf("No more cards in the registry.\n");
		   printf("Match for MSTCP entry [%s] not found!\n",mstcpnetkey);
             RegCloseKey(lnk);
             strcpy(netkey,"dummy");
             return FALSE;
            }
	  	  if (bSuccess != ERROR_SUCCESS)
		   {
		     printf("Can not get card keys from registry for entry # %d!\n",enumcount);
  		     printf("Match for MSTCP entry [%s] not found!\n",mstcpnetkey);
	          RegCloseKey(lnk);
               strcpy(netkey,"dummy");
               return FALSE;
		   }

	     /* now get the bindings subkey */

	      strcpy(checkkey,"ENUM\\Root\\Net\\");
           strcat(checkkey,adapkey);
           strcat(checkkey,"\\BINDINGS");

       	 strcpy(valuekey,"MSTCP\\");
           strcat(valuekey,mstcpnetkey);

           printf("Checking %s for a binding match for %s.\n",checkkey,valuekey);	
           bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,checkkey,&bk);
           if(bSuccess != ERROR_SUCCESS) 
             {
               printf("Interface [%s] not found (in RegOpenKey)! \n",checkkey);
               printf("Not bound to TCPIP! \n");
             }
          else // opened ok now try the regqueryvalue
             {

               valueresultsize = 50;
               bSuccess = RegQueryValueEx(bk, (LPSTR)valuekey, (LPDWORD)NULL, 
                         (LPDWORD)&vtype, (LPBYTE)valueresult, (LPDWORD)&valueresultsize);
               RegCloseKey(bk);
			if(bSuccess == ERROR_SUCCESS)
                 {     	
                   printf("Found match for MSTCP key! [%s]\n",checkkey);
    	              strcpy(netkey,adapkey);
	              RegCloseKey(lnk);
                   return TRUE;
                 }
              else
               {
                printf("[%s] not found (in RegQueryValue)! \n",valuekey);
               }
          }
    /* ok not found with this binding increment enum count and continue */
    ++enumcount;
    
	} /* end of adapter/card enumeration loop */

	/* dead code shouldn't get here */
        printf("ERROR: dead code at end of adapter loop shouldn't be reached\n"); 
 }
      

// ------------------------------------------------------------------------
  
  int get_win95_interfaces()

  {
     HKEY hk, dk, rk, ck;                      /* registry key handle */
     BOOL bSuccess;
     char realkey[200];
     DWORD sizeofrealkey = 200;
     char netkey[50];
     DWORD sizeofnetkey = 50;
     char mstcpnetkey[50];
     DWORD sizeofmstcpnetkey = 50;
     char newkey[50];
     DWORD sizeofnewkey = 50;
     char driverkey[50];
     DWORD sizeofdriverkey = 50;
     char netid[50];		
     DWORD sizeofnettype = 50;
     char nettype[50];		
     DWORD sizeofnetid = 50;
     char subkey[50];
     DWORD sizeofsubkey = 50;

     char checkkey[50];
     DWORD sizeofcheckkey = 50;

     int Done = 0;
     int Done2 = 0;

     /* these need to be big as they are multi_sz in type and hold all ip addresses and subnet mask for a
        given interface */
     char IpAddresses[10000];
     char *ipptr = IpAddresses;
     DWORD sizeofipaddresses = 10000;
     char SubNetMasks[10000];
     char *subptr = SubNetMasks;
     DWORD sizeofsubnetmasks = 10000;
     const int sep = (int)',';
     char *token =  NULL;
     char oneIpAddress[16];
     char oneSubNetMask[16];
     int count = 0;
     char *cp;
     BOOL netkey_found;
     
    /* now get all the netcard (ie 0001) ..._  values which are bound to tcpip */ 

    strcpy(newkey,"ENUM\\Network\\MSTCP");
    printf("opening %s \n",newkey);
    bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,newkey,&hk);
    if(bSuccess != ERROR_SUCCESS)
    {
        printf("Can not get MSTCP Linkage from registry.\n");
        return -1;
    }

     while (!Done)
       {
	     sizeofmstcpnetkey = 50;
	     bSuccess = RegEnumKey(hk, (DWORD)count, (LPTSTR)mstcpnetkey, sizeofmstcpnetkey);
	     if(bSuccess == ERROR_NO_MORE_ITEMS)
		  {
			printf("No more network cards in registry.\n");
			Done = TRUE;
               break;
             }
	
	     if ((bSuccess != ERROR_SUCCESS) && (bSuccess != ERROR_NO_MORE_ITEMS))
		   {
			printf("Can not get network card keys from registry.\n");
			RegCloseKey(hk);
			return -1;
		   }

          ++count;
     
	 /* now the devicedesc here does not specify the dial up so we must get the
            last part off the key and try the key enum//root//net//netkey   */
      /* call new routine here that first checks if the enm\root\net\\netkey
           matches and if so returns otherwise enumerates through all enum\root\net
           keys looking for one that matches based on the bindings subkey.. ie the
           bindings = mstcp\netkey should match */

         sizeofnetkey = 50;
	    printf("-----------------------------------------------------------\n");
         printf("checking MSTCP subkey [%s] to see if it is temporary! \n",mstcpnetkey);
         netkey_found = find_matching_netkey(&mstcpnetkey,&netkey);

         
         if (!netkey_found)
           {
            printf("Cannot find binding match for MSTCP\\%s in the registry.\n",mstcpnetkey);
            printf("Assuming it is not a temporary interface!\n");
            strcpy(nettype,"dummy");
            strcpy(netid,"dummy");
           }

         else
          {
              
           strcpy(checkkey,"ENUM\\Root\\Net\\");
           strcat(checkkey,netkey);
           printf("Checking %s\\DeviceDesc to see if it is a\n temporary (dial up) interface.\n",checkkey);


           /* not sure if this works but on my eisa machine these were not there
              so if they are not there assume they are not temporary .. ie enum\eisa
              for eisa cards instead of enum\\root but I imagine all ras interfaces are like this
              above.. so if not there it is not a ras temporary interface */

	     // get the check value
	     /* check for Dial up adapter */
 	     bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,checkkey,&ck);
          if(bSuccess != ERROR_SUCCESS)
	      {
	       printf("Can not open key [%s] from registry.\n",checkkey);
            printf("Assuming it is not a temporary interface!\n");
            strcpy(nettype,"dummy");
            strcpy(netid,"dummy");
	      }

      else
      {

         // now get the values
	 sizeofnettype = 50;
	 bSuccess = RegQueryValueEx(ck,  /* subkey handle         */
	         "DeviceDesc",           /* value name            */
		    NULL,                   /* must be zero          */
		    NULL,                   /* value type          not required  */
              (LPBYTE) &nettype,      /* address of value data */
              &sizeofnettype);        /* length of value data  */

          if(bSuccess != ERROR_SUCCESS)
          {
            printf("Couldn't fetch Device Desc. value \n");
            printf("Assuming it is not a temporary interface!\n");
            strcpy(nettype,"dummy");
          }

	 sizeofnetid = 50;
	 bSuccess = RegQueryValueEx(ck,  /* subkey handle         */
	         "CompatibleIDs",        /* value name            */
		    NULL,                   /* must be zero          */
		    NULL,                   /* value type          not required  */
              (LPBYTE) &netid,        /* address of value data */
              &sizeofnetid);          /* length of value data  */

      RegCloseKey(ck); // not needed anymore either way
      if(bSuccess != ERROR_SUCCESS)
          {
            printf("Couldn't fetch Compatible ID value \n");
            strcpy(netid,"dummy");
          }

       } // not there
      } // no netkey found (it is not in enum\net\ so it cannot be a temporary one
    
       // go on
      if (((strlen(nettype) >= 15) && 
           (strncmp(strupr(nettype),"DIAL-UP ADAPTER",15) == 0)) ||
          ((strlen(netid) >= 8) &&
	      (strncmp(strupr(netid),"*PNP8387",8) == 0)))
          {
           /* skip it */
	      printf("Skipping Temporary interface: [%s %s]\n",nettype,netid);
          }

         else { // is not temporary interface
            // ok get drivername

	/*now we have the values so we need to get the driver value for the key */
	strcpy(driverkey,"ENUM\\Network\\MSTCP\\");
	strcat(driverkey,mstcpnetkey);

	// get the Driver value
	/*check for Dial up adapter*/
	bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,driverkey,&dk);
	if(bSuccess != ERROR_SUCCESS)
	  {
	    printf("Can not open key [%s] from registry.\n",driverkey);
         RegCloseKey(hk);
	    return -1;
	   }

                // ok it is not temporary so get drivername
		sizeofsubkey = 50;
		bSuccess = RegQueryValueEx(dk,     /* subkey handle         */
	  	      "Driver",                    /* value name            */
		      NULL,                        /* must be zero          */
		      NULL,                        /* value type          not required  */
		      (LPBYTE) &subkey,            /* address of value data */
		      &sizeofsubkey);              /* length of value data  */

               if(bSuccess != ERROR_SUCCESS)
		  {
		    printf("Error in RegQueryValueEx fetching Driver value \n");
		    RegCloseKey(dk);
		    RegCloseKey(hk);
		    return -1;
		  }

          RegCloseKey(dk); //driver key not needed any longer

          // ok we now have the vlaue
	     printf("have driver value = %s \n",subkey);
	     
          // now open the real key
          strcpy(realkey,"SYSTEM\\CurrentControlSet\\Services\\Class\\");
          strcat(realkey,subkey);
	     
          printf("opening Network key: %s \n",realkey);
          bSuccess = RegOpenKey(HKEY_LOCAL_MACHINE,realkey,&rk);
          if(bSuccess != ERROR_SUCCESS)
            {
             printf("error opening real network key [%s].\n",realkey);
             RegCloseKey(hk);
             return -1;
            }
        
           printf("getting ip address ...\n");
           sizeofipaddresses = 10000;
           bSuccess = RegQueryValueEx(rk,     /* subkey handle         */
                "IPAddress",                  /* value name            */
                 NULL,                        /* must be zero          */
                 NULL,                        /* value type          not required  */
                 (LPBYTE) &IpAddresses,       /* address of value data */
                 &sizeofipaddresses);         /* length of value data  */

           if(bSuccess != ERROR_SUCCESS)
              {
               printf("Error in RegQueryValueEx fetching IPAddress parameter! \n");
               RegCloseKey(rk);
               RegCloseKey(hk);
               return -1;
              }
              
          printf("ipaddress block: size = %d\n",sizeofipaddresses);
          printf("-----------------------------------------------------------\n");
          cp = IpAddresses;
          { int i;
          for (i=0; i<(int)sizeofipaddresses; i++)
            { 
             printf("%c",*cp);
             ++cp;
            }
          printf("\n-----------------------------------------------------------\n");
          }

           /* ok now get the subnetmask */
           sizeofsubnetmasks = 10000;
           printf("Getting subnetmask block\n");
           bSuccess = RegQueryValueEx(rk,     /* subkey handle         */
              "IPMask",                       /* value name            */
               NULL,                          /* must be zero          */
               NULL,                          /* value type          not required  */
               (LPBYTE) &SubNetMasks,         /* address of value data */
               &sizeofsubnetmasks);           /* length of value data  */
   
           if(bSuccess != ERROR_SUCCESS)
              {
               printf("Error in RegQueryValueEx fetching IPMask parameter!\n");
               RegCloseKey(rk);
               RegCloseKey(hk);
               return -1;
              }

          printf("subnet block: size = %d\n",sizeofsubnetmasks);
          printf("-----------------------------------------------------------\n");
          cp = SubNetMasks;
          { int i;
          for (i=0; i<(int)sizeofsubnetmasks; i++)
            { 
             printf("%c",*cp);
             ++cp;
            }
          printf("\n-----------------------------------------------------------\n");
          }
          RegCloseKey(rk);
          /* ok now that we have some addresses and subnet masks go through each one and add to our structure... */
          /* multi_sz strings are terminated by two \0 in a row */
          /* win95 is terminated by commas   */

        ipptr = IpAddresses;
        subptr = SubNetMasks;
        Done2 = 0;
        token = NULL;
        
       /* lgk change here win95 mutli addresses are separated by commas not
          spaces like NT, so replace the commas with spaces so the old
          loop works  */

       token = strchr(ipptr,sep);
       while (token != NULL)
        {
         *token = ' ';
         token = strchr(ipptr,sep);
        }

        /* now handle subnet block */
       token = strchr(subptr,sep);
       while (token != NULL)
        {
         *token = ' ';
         token = strchr(subptr,sep);
        }

      while (!Done2)
        {
         if (sscanf(ipptr,"%s",oneIpAddress) != EOF)
           ipptr+= strlen(oneIpAddress) + 1; /* add one for terminator \0 */
         else Done2 = 1;
         
         if (sscanf(subptr,"%s",oneSubNetMask) != EOF)
           subptr += strlen(oneSubNetMask) + 1;
         else Done2 = 1;

         /* now add to interface structure */
         if (!Done2)                  
          {
           printf("IP address = %s \n",oneIpAddress);
           printf("Subnet mask = %s \n",oneSubNetMask);
           if (((char *)ipptr == '\0') || ((char *)subptr == '\0')) 
             Done = 1;

	     }
	    } // not done loop
        } // not temporary interface
       } // loop (while) through more things bound to MSTCP
 
    RegCloseKey(hk); // done with top while so close key
    return 0;
  }


void main()

 {
      get_win95_interfaces();
    
 }

