メイン   モジュール   デー タ構造   ファイルリスト   データフィールド   グローバル   関連ページ   注意事項   English

Packet32.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999, 2000
00003  *  Politecnico di Torino.  All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that: (1) source code distributions
00007  * retain the above copyright notice and this paragraph in its entirety, (2)
00008  * distributions including binary code include the above copyright notice and
00009  * this paragraph in its entirety in the documentation or other materials
00010  * provided with the distribution, and (3) all advertising materials mentioning
00011  * features or use of this software display the following acknowledgement:
00012  * ``This product includes software developed by the Politecnico
00013  * di Torino, and its contributors.'' Neither the name of
00014  * the University nor the names of its contributors may be used to endorse
00015  * or promote products derived from this software without specific prior
00016  * written permission.
00017  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00018  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00020  */
00021 
00022 #define UNICODE 1
00023 
00024 #include <packet32.h>
00025 
00026 #include <windows.h>
00027 #include <windowsx.h>
00028 
00029 #include <ntddndis.h>
00030 
00031 
00033 TCHAR   szWindowTitle[] = TEXT("PACKET.DLL");
00034 
00035 #if _DBG
00036 #define ODS(_x) OutputDebugString(TEXT(_x))
00037 #define ODSEx(_x, _y)
00038 #else
00039 #ifdef _DEBUG_TO_FILE
00040 #include <stdio.h>
00044 #define ODS(_x) { \
00045     FILE *f; \
00046     f = fopen("winpcap_debug.txt", "a"); \
00047     fprintf(f, "%s", _x); \
00048     fclose(f); \
00049 }
00050 
00054 #define ODSEx(_x, _y) { \
00055     FILE *f; \
00056     f = fopen("winpcap_debug.txt", "a"); \
00057     fprintf(f, _x, _y); \
00058     fclose(f); \
00059 }
00060 
00061 
00062 
00063 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName);
00064 #else
00065 #define ODS(_x)     
00066 #define ODSEx(_x, _y)
00067 #endif
00068 #endif
00069 
00070 //service handles
00071 SC_HANDLE scmHandle = NULL;
00072 SC_HANDLE srvHandle = NULL;
00073 LPCTSTR NPFServiceName = TEXT("NPF");
00074 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter");
00075 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF");
00076 LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\npf.sys");
00077 
00078 //---------------------------------------------------------------------------
00079 
00084 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
00085 {
00086     BOOLEAN Status=TRUE;
00087 
00088     switch ( Reason )
00089     {
00090     case DLL_PROCESS_ATTACH:
00091         
00092         ODS("************Packet32: DllMain************\n");
00093         
00094 #ifdef _DEBUG_TO_FILE
00095         // dump a bunch of registry keys useful for debug to file
00096         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
00097             "adapters.reg");
00098         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip",
00099             "tcpip.reg");
00100         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF",
00101             "npf.reg");
00102         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
00103             "services.reg");
00104 #endif
00105         break;
00106 
00107         case DLL_PROCESS_DETACH:
00108             break;
00109 
00110         default:
00111             break;
00112     }
00113 
00114     return Status;
00115 }
00116 
00123 WCHAR* SChar2WChar(char* string)
00124 {
00125     WCHAR* TmpStr;
00126     TmpStr=(WCHAR*) malloc ((strlen(string)+2)*sizeof(WCHAR));
00127 
00128     MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2));
00129 
00130     return TmpStr;
00131 }
00132 
00142 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
00143 {
00144     BOOLEAN    Status;
00145     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
00146     PPACKET_OID_DATA  OidData;
00147 
00148     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
00149     if (OidData == NULL) {
00150         ODS("PacketSetMaxLookaheadsize failed\n");
00151         return FALSE;
00152     }
00153 
00154     //set the size of the lookahead buffer to the maximum available by the the NIC driver
00155     OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
00156     OidData->Length=sizeof(ULONG);
00157     Status=PacketRequest(AdapterObject,FALSE,OidData);
00158     OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
00159     Status=PacketRequest(AdapterObject,TRUE,OidData);
00160     GlobalFreePtr(OidData);
00161     return Status;
00162 }
00163 
00174 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
00175 {
00176     DWORD BytesReturned;
00177     TCHAR EventName[39];
00178 
00179     // this tells the terminal service to retrieve the event from the global namespace
00180     wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
00181 
00182     // retrieve the name of the shared event from the driver
00183     if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE;
00184 
00185     EventName[20]=0; // terminate the string
00186 
00187     // open the shared event
00188     AdapterObject->ReadEvent=CreateEvent(NULL,
00189                                          TRUE,
00190                                          FALSE,
00191                                          EventName);
00192 
00193     // in NT4 "Global\" is not automatically ignored: try to use simply the event name
00194     if(GetLastError()!=ERROR_ALREADY_EXISTS){
00195         if(AdapterObject->ReadEvent != NULL)
00196             CloseHandle(AdapterObject->ReadEvent);
00197         
00198         // open the shared event
00199         AdapterObject->ReadEvent=CreateEvent(NULL,
00200             TRUE,
00201             FALSE,
00202             EventName+7);
00203     }   
00204 
00205     if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
00206         ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
00207         return FALSE;
00208     }
00209 
00210     AdapterObject->ReadTimeOut=0;
00211 
00212     return TRUE;
00213 }
00214 
00224 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle)
00225 {
00226     BOOL result = FALSE;
00227     ULONG err;
00228     
00229     ODS("installdriver\n");
00230     
00231     *srvHandle = CreateService(ascmHandle, 
00232         NPFServiceName,
00233         NPFServiceDesc,
00234         SERVICE_ALL_ACCESS,
00235         SERVICE_KERNEL_DRIVER,
00236         SERVICE_DEMAND_START,
00237         SERVICE_ERROR_NORMAL,
00238         NPFDriverPath,
00239         NULL, NULL, NULL, NULL, NULL);
00240     if (*srvHandle == NULL) 
00241     {
00242         if (GetLastError() == ERROR_SERVICE_EXISTS) 
00243         {
00244             //npf.sys already existed
00245             result = TRUE;
00246         }
00247     }
00248     else 
00249     {
00250         //Created service for npf.sys
00251         result = TRUE;
00252     }
00253     if (result == TRUE) 
00254         if (*srvHandle != NULL)
00255             CloseServiceHandle(*srvHandle);
00256 
00257     if(result == FALSE){
00258         err = GetLastError();
00259         if(err != 2)
00260             ODSEx("PacketInstallDriver failed, Error=%d\n",err);
00261     }
00262     return result;
00263     
00264 }
00265 
00275 ULONG inet_addrU(const WCHAR *cp)
00276 {
00277     ULONG val, part;
00278     WCHAR c;
00279     int i;
00280 
00281     val = 0;
00282     for (i = 0; i < 4; i++) {
00283         part = 0;
00284         while ((c = *cp++) != '\0' && c != '.') {
00285             if (c < '0' || c > '9')
00286                 return -1;
00287             part = part*10 + (c - '0');
00288         }
00289         if (part > 255)
00290             return -1;  
00291         val = val | (part << i*8);
00292         if (i == 3) {
00293             if (c != '\0')
00294                 return -1;  // extra gunk at end of string 
00295         } else {
00296             if (c == '\0')
00297                 return -1;  // string ends early 
00298         }
00299     }
00300     return val;
00301 }
00302 
00312 #ifdef _DEBUG_TO_FILE
00313 
00314 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
00315 {
00316     CHAR Command[256];
00317 
00318     strcpy(Command, "regedit /e ");
00319     strcat(Command, FileName);
00320     strcat(Command, " ");
00321     strcat(Command, KeyName);
00322 
00324     system(Command);
00325 
00326     return TRUE;
00327 }
00328 #endif
00329 
00330 //---------------------------------------------------------------------------
00331 // PUBLIC API
00332 //---------------------------------------------------------------------------
00333 
00342 
00343 char PacketLibraryVersion[] = "3.0 alpha3"; 
00344 
00349 PCHAR PacketGetVersion(){
00350     return PacketLibraryVersion;
00351 }
00352 
00369 BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
00370 {
00371     BOOLEAN    Status;
00372     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
00373     PPACKET_OID_DATA  OidData;
00374 
00375     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
00376     if (OidData == NULL) {
00377         ODS("PacketGetNetType failed\n");
00378         return FALSE;
00379     }
00380     //get the link-layer type
00381     OidData->Oid = OID_GEN_MEDIA_IN_USE;
00382     OidData->Length = sizeof (ULONG);
00383     Status = PacketRequest(AdapterObject,FALSE,OidData);
00384     type->LinkType=*((UINT*)OidData->Data);
00385 
00386     //get the link-layer speed
00387     OidData->Oid = OID_GEN_LINK_SPEED;
00388     OidData->Length = sizeof (ULONG);
00389     Status = PacketRequest(AdapterObject,FALSE,OidData);
00390     type->LinkSpeed=*((UINT*)OidData->Data)*100;
00391     GlobalFreePtr (OidData);
00392 
00393     ODSEx("Media:%d ",type->LinkType);
00394     ODSEx("Speed=%d\n",type->LinkSpeed);
00395 
00396     return Status;
00397 }
00398 
00407 BOOL PacketStopDriver()
00408 {
00409     SC_HANDLE       scmHandle;
00410     SC_HANDLE       schService;
00411     BOOL            ret;
00412     SERVICE_STATUS  serviceStatus;
00413 
00414     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00415     
00416     if(scmHandle != NULL){
00417         
00418         schService = OpenService (scmHandle,
00419             NPFServiceName,
00420             SERVICE_ALL_ACCESS
00421             );
00422         
00423         if (schService != NULL)
00424         {
00425             
00426             ret = ControlService (schService,
00427                 SERVICE_CONTROL_STOP,
00428                 &serviceStatus
00429                 );
00430             if (!ret)
00431             {
00432             }
00433             
00434             CloseServiceHandle (schService);
00435             
00436             CloseServiceHandle(scmHandle);
00437             
00438             return ret;
00439         }
00440     }
00441     
00442     return FALSE;
00443 
00444 }
00445 
00468 LPADAPTER PacketOpenAdapter(LPTSTR AdapterName)
00469 {
00470     LPADAPTER lpAdapter;
00471     BOOLEAN Result;
00472     char *AdapterNameA;
00473     WCHAR *AdapterNameU;
00474     DWORD error;
00475     SC_HANDLE svcHandle = NULL;
00476     LONG KeyRes;
00477     HKEY PathKey;
00478     SERVICE_STATUS SStat;
00479     BOOLEAN QuerySStat;
00480     WCHAR SymbolicLink[128];
00481 
00482     ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName)
00483 
00484     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00485     
00486     if(scmHandle == NULL){
00487         error = GetLastError();
00488         ODSEx("OpenSCManager failed! Error=%d\n", error);
00489     }
00490     else{
00491         // check if the NPF registry key is already present
00492         // this means that the driver is already installed and that we don't need to call PacketInstallDriver
00493         KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00494             NPFRegistryLocation,
00495             0,
00496             KEY_READ,
00497             &PathKey);
00498         
00499         if(KeyRes != ERROR_SUCCESS)
00500         {
00501             Result = PacketInstallDriver(scmHandle,&svcHandle);
00502         }
00503         else
00504         {
00505             Result = TRUE;
00506             RegCloseKey(PathKey);
00507         }
00508         
00509         if (Result) 
00510         {
00511             
00512             srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
00513             if (srvHandle != NULL)
00514             {
00515                 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
00516                 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
00517                 
00518                 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
00519                 {
00520                     ODS("Calling startservice\n");
00521                     if (StartService(srvHandle, 0, NULL)==0)
00522                     { 
00523                         error = GetLastError();
00524                         if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS)
00525                         {
00526                             SetLastError(error);
00527                             if (scmHandle != NULL) 
00528                                 CloseServiceHandle(scmHandle);
00529                             error = GetLastError();
00530                             ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
00531                             return NULL;
00532                         }
00533                     }               
00534                 }
00535 
00536                 CloseServiceHandle( srvHandle );
00537                 srvHandle = NULL;
00538 
00539             }
00540             else
00541             {
00542                 error = GetLastError();
00543                 ODSEx("OpenService failed! Error=%d", error);
00544             }
00545         }
00546         else
00547         {
00548             if(KeyRes != ERROR_SUCCESS)
00549                 Result = PacketInstallDriver(scmHandle,&svcHandle);
00550             else
00551                 Result = TRUE;
00552             
00553             if (Result) {
00554                 
00555                 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
00556                 if (srvHandle != NULL){
00557                     
00558                     QuerySStat = QueryServiceStatus(srvHandle, &SStat);
00559                     ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
00560                     
00561                     if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
00562                         
00563                         ODS("Calling startservice\n");
00564                         
00565                         if (StartService(srvHandle, 0, NULL)==0){ 
00566                             error = GetLastError();
00567                             if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
00568                                 SetLastError(error);
00569                                 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00570                                 ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
00571                                 return NULL;
00572                             }
00573                         }
00574                     }
00575                     
00576                     CloseServiceHandle( srvHandle );
00577                     srvHandle = NULL;
00578 
00579                 }
00580                 else{
00581                     error = GetLastError();
00582                     ODSEx("OpenService failed! Error=%d", error);
00583                 }
00584             }
00585         }
00586     }
00587 
00588     if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00589 
00590     AdapterNameA=(char*)AdapterName;
00591     if(AdapterNameA[1]!=0){ //ASCII
00592         AdapterNameU=SChar2WChar(AdapterNameA);
00593         AdapterName=AdapterNameU;
00594     } else {            //Unicode
00595         AdapterNameU=NULL;
00596     }
00597     
00598     lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER));
00599     if (lpAdapter==NULL)
00600     {
00601         ODS("PacketOpenAdapter: GlobalAlloc Failed\n");
00602         error=GetLastError();
00603         if (AdapterNameU != NULL) free(AdapterNameU);
00604         //set the error to the one on which we failed
00605         SetLastError(error);
00606         ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n");
00607         return NULL;
00608     }
00609     lpAdapter->NumWrites=1;
00610 
00611 
00612 
00613     if (LOWORD(GetVersion()) == 4)
00614         wsprintf(SymbolicLink,TEXT("\\\\.\\%s"),&AdapterName[8]);
00615     else
00616         wsprintf(SymbolicLink,TEXT("\\\\.\\Global\\%s"),&AdapterName[8]);
00617     
00618     // Copy  only the bytes that fit in the adapter structure.
00619     // Note that lpAdapter->SymbolicLink is present for backward compatibility but will
00620     // never be used by the apps
00621     memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
00622 
00623     //try if it is possible to open the adapter immediately
00624     lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
00625         0,NULL,OPEN_EXISTING,0,0);
00626     
00627     if (lpAdapter->hFile != INVALID_HANDLE_VALUE) 
00628     {
00629 
00630         if(PacketSetReadEvt(lpAdapter)==FALSE){
00631             error=GetLastError();
00632             ODS("PacketOpenAdapter: Unable to open the read event\n");
00633             if (AdapterNameU != NULL)
00634                 free(AdapterNameU);
00635             GlobalFreePtr(lpAdapter);
00636             //set the error to the one on which we failed
00637             SetLastError(error);
00638             ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error);
00639             return NULL;
00640         }       
00641         
00642         PacketSetMaxLookaheadsize(lpAdapter);
00643         if (AdapterNameU != NULL)
00644             free(AdapterNameU);
00645         return lpAdapter;
00646     }
00647 
00648 
00649     error=GetLastError();
00650     if (AdapterNameU != NULL)
00651         free(AdapterNameU);
00652     GlobalFreePtr(lpAdapter);
00653     //set the error to the one on which we failed
00654     SetLastError(error);
00655     ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error);
00656     return NULL;
00657 
00658 }
00659 
00666 VOID PacketCloseAdapter(LPADAPTER lpAdapter)
00667 {
00668     CloseHandle(lpAdapter->hFile);
00669     SetEvent(lpAdapter->ReadEvent);
00670     CloseHandle(lpAdapter->ReadEvent);
00671     GlobalFreePtr(lpAdapter);
00672 }
00673 
00686 LPPACKET PacketAllocatePacket(void)
00687 {
00688 
00689     LPPACKET    lpPacket;
00690     lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
00691     if (lpPacket==NULL)
00692     {
00693         ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
00694         return NULL;
00695     }
00696     return lpPacket;
00697 }
00698 
00707 VOID PacketFreePacket(LPPACKET lpPacket)
00708 
00709 {
00710     GlobalFreePtr(lpPacket);
00711 }
00712 
00729 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)
00730 
00731 {
00732     lpPacket->Buffer = Buffer;
00733     lpPacket->Length = Length;
00734     lpPacket->ulBytesReceived = 0;
00735     lpPacket->bIoComplete = FALSE;
00736 }
00737 
00768 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
00769 {
00770     BOOLEAN res;
00771 
00772     if((int)AdapterObject->ReadTimeOut != -1)
00773         WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
00774 
00775     res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
00776 
00777     return res;
00778 }
00779 
00809 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
00810 
00811 {
00812     DWORD        BytesTransfered;
00813     
00814     return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
00815 }
00816 
00817 
00845 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
00846 {
00847     BOOLEAN         Res;
00848     DWORD           BytesTransfered, TotBytesTransfered=0;
00849     struct timeval  BufStartTime;
00850     LARGE_INTEGER   StartTicks, CurTicks, TargetTicks, TimeFreq;
00851 
00852 
00853     ODS("PacketSendPackets");
00854 
00855     // Obtain starting timestamp of the buffer
00856     BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec;
00857     BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
00858 
00859     // Retrieve the reference time counters
00860     QueryPerformanceCounter(&StartTicks);
00861     QueryPerformanceFrequency(&TimeFreq);
00862 
00863     CurTicks.QuadPart = StartTicks.QuadPart;
00864 
00865     do{
00866         // Send the data to the driver
00867         Res = DeviceIoControl(AdapterObject->hFile,
00868             (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC,
00869             (PCHAR)PacketBuff + TotBytesTransfered,
00870             Size - TotBytesTransfered,
00871             NULL,
00872             0,
00873             &BytesTransfered,
00874             NULL);
00875 
00876         TotBytesTransfered += BytesTransfered;
00877 
00878         // calculate the time interval to wait before sending the next packet
00879         TargetTicks.QuadPart = StartTicks.QuadPart +
00880         (LONGLONG)
00881         ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 +
00882         (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *
00883         (TimeFreq.QuadPart) / 1000000;
00884 
00885         // Exit from the loop on termination or error
00886         if(TotBytesTransfered >= Size || Res != TRUE)
00887             break;
00888         
00889         // Wait until the time interval has elapsed
00890         while( CurTicks.QuadPart <= TargetTicks.QuadPart )
00891             QueryPerformanceCounter(&CurTicks);
00892 
00893     }
00894     while(TRUE);
00895 
00896     return TotBytesTransfered;
00897 }
00898 
00917 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
00918 {
00919     DWORD BytesReturned;
00920     return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
00921 }
00922 
00959 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
00960 {
00961     DWORD BytesReturned;
00962 
00963     return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
00964 }
00965 
00980 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len)
00981 {
00982     DWORD       BytesReturned;
00983     WCHAR   *FileName;
00984     BOOLEAN res;
00985     WCHAR   NameWithPath[1024];
00986     int     TStrLen;
00987     WCHAR   *NamePos;
00988 
00989     if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII
00990         FileName=SChar2WChar(name);
00991         len*=2;
00992     } 
00993     else {  //Unicode
00994         FileName=name;
00995     }
00996 
00997     TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos);
00998 
00999     len=TStrLen*2+2;  //add the terminating null character
01000 
01001     // Try to catch malformed strings
01002     if(len>2048){
01003         if(((PUCHAR)name)[1]!=0 && len>1) free(FileName);
01004         return FALSE;
01005     }
01006 
01007     res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL);
01008     free(FileName);
01009     return res;
01010 }
01011 
01027 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks)
01028 {
01029     DWORD       BytesReturned;
01030     UINT valbuff[2];
01031 
01032     valbuff[0] = maxfilesize;
01033     valbuff[1] = maxnpacks;
01034 
01035     return DeviceIoControl(AdapterObject->hFile,
01036         pBIOCSETDUMPLIMITS,
01037         valbuff,
01038         sizeof valbuff,
01039         NULL,
01040         0,
01041         &BytesReturned,
01042         NULL);  
01043 }
01044 
01058 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
01059 {
01060     DWORD       BytesReturned;
01061     int     IsDumpEnded;
01062     BOOLEAN res;
01063 
01064     if(sync)
01065         WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
01066 
01067     res = DeviceIoControl(AdapterObject->hFile,
01068         pBIOCISDUMPENDED,
01069         NULL,
01070         0,
01071         &IsDumpEnded,
01072         4,
01073         &BytesReturned,
01074         NULL);
01075 
01076     if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished
01077 
01078     return (BOOLEAN)IsDumpEnded;
01079 }
01080 
01100 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
01101 {
01102     return AdapterObject->ReadEvent;
01103 }
01104 
01113 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
01114 {
01115     DWORD BytesReturned;
01116     return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
01117 }
01118 
01131 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
01132 {
01133     DWORD BytesReturned;
01134     int DriverTimeOut=-1;
01135 
01136     AdapterObject->ReadTimeOut=timeout;
01137 
01138     return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
01139 }
01140 
01157 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
01158 {
01159     DWORD BytesReturned;
01160     return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
01161 }
01162 
01183 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp)
01184 {
01185     DWORD BytesReturned;
01186     return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
01187 }
01188 
01202 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
01203 {
01204     BOOLEAN Res;
01205     DWORD BytesReturned;
01206     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
01207 
01208     Res = DeviceIoControl(AdapterObject->hFile,
01209         pBIOCGSTATS,
01210         NULL,
01211         0,
01212         &tmpstat,
01213         sizeof(struct bpf_stat),
01214         &BytesReturned,
01215         NULL);
01216 
01217     // Copy only the first two values retrieved from the driver
01218     s->bs_recv = tmpstat.bs_recv;
01219     s->bs_drop = tmpstat.bs_drop;
01220 
01221     return Res;
01222 }
01223 
01236 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
01237 {
01238     BOOLEAN Res;
01239     DWORD BytesReturned;
01240     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
01241 
01242     Res = DeviceIoControl(AdapterObject->hFile,
01243         pBIOCGSTATS,
01244         NULL,
01245         0,
01246         &tmpstat,
01247         sizeof(struct bpf_stat),
01248         &BytesReturned,
01249         NULL);
01250 
01251     s->bs_recv = tmpstat.bs_recv;
01252     s->bs_drop = tmpstat.bs_drop;
01253     s->ps_ifdrop = tmpstat.ps_ifdrop;
01254     s->bs_capt = tmpstat.bs_capt;
01255 
01256     return Res;
01257 }
01258 
01271 BOOLEAN PacketRequest(LPADAPTER  AdapterObject,BOOLEAN Set,PPACKET_OID_DATA  OidData)
01272 {
01273     DWORD       BytesReturned;
01274     BOOLEAN     Result;
01275 
01276     Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID,
01277                            OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
01278                            sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);
01279     
01280     // output some debug info
01281     ODSEx("PacketRequest, OID=%d ", OidData->Oid);
01282     ODSEx("Length=%d ", OidData->Length);
01283     ODSEx("Set=%d ", Set);
01284     ODSEx("Res=%d\n", Result);
01285 
01286     return Result;
01287 }
01288 
01305 BOOLEAN PacketSetHwFilter(LPADAPTER  AdapterObject,ULONG Filter)
01306 {
01307     BOOLEAN    Status;
01308     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
01309     PPACKET_OID_DATA  OidData;
01310 
01311     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
01312     if (OidData == NULL) {
01313         ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
01314         return FALSE;
01315     }
01316     OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
01317     OidData->Length=sizeof(ULONG);
01318     *((PULONG)OidData->Data)=Filter;
01319     Status=PacketRequest(AdapterObject,TRUE,OidData);
01320     GlobalFreePtr(OidData);
01321     return Status;
01322 }
01323 
01353 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG  BufferSize)
01354 {
01355   HKEY      LinkageKey,AdapKey, OneAdapKey;
01356     DWORD       RegKeySize=0;
01357   LONG      Status;
01358     ULONG       Result;
01359     PTSTR       BpStr;
01360     char        *TTpStr,*DpStr,*DescBuf;
01361     LPADAPTER   adapter;
01362   PPACKET_OID_DATA  OidData;
01363     int         i=0,k,rewind;
01364     DWORD       dim;
01365     TCHAR       AdapName[256];
01366 
01367   ODSEx("PacketGetAdapterNames: BufferSize=%d\n",*BufferSize);
01368 
01369   OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512);
01370   if (OidData == NULL) {
01371       ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
01372       return FALSE;
01373   }
01374 
01375   Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
01376                       TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
01377                         0,
01378                         KEY_READ,
01379                         &AdapKey);
01380   if ( Status != ERROR_SUCCESS ){
01381     ODS("PacketGetAdapterNames: RegOpenKeyEx ( Class\{networkclassguid} ) Failed\n");
01382     return FALSE;
01383   }
01384 
01385     // Get the size to allocate for the original device names
01386     while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
01387     {
01388         Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&OneAdapKey);
01389     if ( Status != ERROR_SUCCESS ){
01390         RegCloseKey(AdapKey);
01391       ODS("PacketGetAdapterNames: RegOpenKeyEx ( OneAdapKey ) Failed\n");
01392       return FALSE;
01393     }
01394     
01395         Status=RegOpenKeyEx(OneAdapKey,L"Linkage",0,KEY_READ,&LinkageKey);
01396     if ( Status != ERROR_SUCCESS ){
01397       RegCloseKey( OneAdapKey );
01398         RegCloseKey(AdapKey);
01399       ODS("PacketGetAdapterNames: RegOpenKeyEx ( LinkageKey ) Failed\n");
01400       return FALSE;
01401     }
01402 
01403     Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,NULL,&dim);
01404 
01405     RegCloseKey( OneAdapKey );
01406     RegCloseKey( LinkageKey );
01407 
01408         i++;
01409         if(Status!=ERROR_SUCCESS) continue;
01410         RegKeySize+=dim;
01411   } // while enum reg key still find keys
01412     
01413     // Allocate the memory for the original device names
01414     ODSEx("Need %d bytes for the names\n", RegKeySize+2);
01415     BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
01416     if (BpStr == NULL || RegKeySize > *BufferSize) {
01417         ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
01418         GlobalFreePtr(OidData);
01419         return FALSE;
01420     }
01421 
01422     k=0;
01423     i=0;
01424 
01425   ODS("PacketGetAdapterNames: Cycling through the adapters:\n");
01426 
01427     // Copy the names to the buffer
01428     while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
01429     {
01430         WCHAR UpperBindStr[64];
01431 
01432         i++;
01433         ODSEx(" %d) ", i);
01434 
01435         Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&OneAdapKey);
01436     if ( Status != ERROR_SUCCESS ){
01437         RegCloseKey(AdapKey);
01438       ODS("PacketGetAdapterNames: RegOpenKeyEx ( OneAdapKey ) Failed\n");
01439       return FALSE;
01440     }
01441         Status=RegOpenKeyEx(OneAdapKey,L"Linkage",0,KEY_READ,&LinkageKey);
01442     if ( Status != ERROR_SUCCESS ){
01443       RegCloseKey( OneAdapKey );
01444         RegCloseKey(AdapKey);
01445       ODS("PacketGetAdapterNames: RegOpenKeyEx ( LinkageKey ) Failed\n");
01446       return FALSE;
01447     }
01448 
01449         dim=sizeof(UpperBindStr);
01450         Status=RegQueryValueEx(LinkageKey,L"UpperBind",NULL,NULL,(PUCHAR)UpperBindStr,&dim);
01451         
01452         ODSEx("UpperBind=%S ", UpperBindStr);
01453 
01454         dim=RegKeySize-k;
01455         Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,(LPBYTE)BpStr+k,&dim);
01456         if(Status!=ERROR_SUCCESS){
01457       RegCloseKey( OneAdapKey );
01458       RegCloseKey( LinkageKey );
01459             ODS("Name = SKIPPED (error reading the key)\n");
01460             continue;
01461         }
01462 
01463     RegCloseKey( OneAdapKey );
01464     RegCloseKey( LinkageKey );
01465         ODSEx("Name = %S\n", (LPBYTE)BpStr+k);
01466 
01467         k+=dim-2;
01468   } // while enum reg keys
01469 
01470     RegCloseKey(AdapKey);
01471 
01472 #ifdef _DEBUG_TO_FILE
01473     //dump BpStr for debug purposes
01474     ODS("Dumping BpStr:");
01475     {
01476         FILE *f;
01477         f = fopen("winpcap_debug.txt", "a");
01478         for(i=0;i<k;i++){
01479             if(!(i%32))fprintf(f, "\n ");
01480             fprintf(f, "%c " , *((LPBYTE)BpStr+i));
01481         }
01482         fclose(f);
01483     }
01484     ODS("\n");
01485 #endif
01486 
01487     
01488     if (k != 0)
01489   {
01490     DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
01491 
01492         if (DescBuf == NULL) {
01493             GlobalFreePtr (BpStr);
01494           GlobalFreePtr(OidData);
01495             return FALSE;
01496         }
01497         DpStr=DescBuf;
01498                 
01499         for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;)
01500     {
01501             
01502             if(k+wcslen(BpStr+i)+30 > *BufferSize){
01503                 // Input buffer too small
01504                 GlobalFreePtr(OidData);
01505                 GlobalFreePtr (BpStr);
01506                 GlobalFreePtr (DescBuf);
01507                 ODS("PacketGetAdapterNames: Input buffer too small!\n");
01508                 return FALSE;
01509             }
01510 
01511             // Create the device name
01512             rewind=k;
01513             memcpy(pStr+k,BpStr+i,16);
01514             memcpy(pStr+k+8,TEXT("NPF_"),8);
01515             i+=8;
01516             k+=12;
01517             while(BpStr[i-1]!=0){
01518                 pStr[k++]=BpStr[i++];
01519             }
01520 
01521             // Open the adapter
01522             adapter=PacketOpenAdapter(pStr+rewind);
01523             if(adapter==NULL){
01524                 k=rewind;
01525                 continue;
01526             }
01527 
01528             // Retrieve the description
01529             OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
01530             OidData->Length = 256;
01531             ZeroMemory(OidData->Data,256);
01532             Status = PacketRequest(adapter,FALSE,OidData);
01533             if(Status==0 || ((char*)OidData->Data)[0]==0){
01534                 k=rewind;
01535                 continue;
01536             }
01537 
01538             ODSEx("Adapter Description=%s\n\n",OidData->Data);
01539 
01540             // Copy the description
01541             TTpStr=(char*)(OidData->Data);
01542             while(*TTpStr!=0){
01543                 *DpStr++=*TTpStr++;
01544             }
01545             *DpStr++=*TTpStr++;
01546             
01547             // Close the adapter
01548             PacketCloseAdapter(adapter);
01549             
01550     } // for end - parse through string
01551         *DpStr=0;
01552 
01553         pStr[k++]=0;
01554         pStr[k]=0;
01555 
01556         if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
01557             memcpy(pStr+k,DescBuf,DpStr-DescBuf);
01558         else{
01559           GlobalFreePtr(OidData);
01560             GlobalFreePtr (BpStr);
01561             GlobalFreePtr (DescBuf);
01562             ODS("\nPacketGetAdapterNames: ended with failure\n");
01563             return FALSE;
01564         }
01565 
01566       GlobalFreePtr(OidData);
01567         GlobalFreePtr (BpStr);
01568         GlobalFreePtr (DescBuf);
01569         ODS("\nPacketGetAdapterNames: ended correctly\n");
01570         return TRUE;
01571   } // if k != 0
01572     else{
01573       DWORD      RegType;
01574 
01575         ODS("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings.\n");
01576 
01577         GlobalFreePtr (BpStr);
01578 
01579         Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"),0,KEY_READ,&LinkageKey);
01580         if (Status == ERROR_SUCCESS)
01581         {
01582             // Retrieve the length of the key
01583             Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,NULL,&RegKeySize);
01584             // Allocate the buffer
01585             BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
01586             if (BpStr == NULL || RegKeySize > *BufferSize) {
01587                 GlobalFreePtr(OidData);
01588                 return FALSE;
01589             }
01590             Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,(LPBYTE)BpStr,&RegKeySize);
01591             RegCloseKey(LinkageKey);
01592         }
01593         
01594         if (Status==ERROR_SUCCESS){
01595             
01596             DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
01597             if (DescBuf == NULL) {
01598                 GlobalFreePtr (BpStr);
01599                 GlobalFreePtr(OidData);
01600                 return FALSE;
01601             }
01602             DpStr=DescBuf;
01603             
01604             for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;){
01605                 
01606                 if(k+wcslen(BpStr+i)+30 > *BufferSize){
01607                     // Input buffer too small
01608                     GlobalFreePtr(OidData);
01609                     GlobalFreePtr (BpStr);
01610                     GlobalFreePtr (DescBuf);
01611                     return FALSE;
01612                 }
01613                 
01614                 // Create the device name
01615                 rewind=k;
01616                 memcpy(pStr+k,BpStr+i,16);
01617                 memcpy(pStr+k+8,TEXT("NPF_"),8);
01618                 i+=8;
01619                 k+=12;
01620                 while(BpStr[i-1]!=0){
01621                     pStr[k++]=BpStr[i++];
01622                 }
01623                 
01624                 // Open the adapter
01625                 adapter=PacketOpenAdapter(pStr+rewind);
01626                 if(adapter==NULL){
01627                     k=rewind;
01628                     continue;
01629                 }
01630                 
01631                 // Retrieve the description
01632                 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
01633                 OidData->Length = 256;
01634                 Status = PacketRequest(adapter,FALSE,OidData);
01635                 if(Status==0 || ((char*)OidData->Data)[0]==0){
01636                     k=rewind;
01637                     continue;
01638                 }
01639                 
01640                 // Copy the description
01641                 TTpStr=(char*)(OidData->Data);
01642                 while(*TTpStr!=0){
01643                     *DpStr++=*TTpStr++;
01644                 }
01645                 *DpStr++=*TTpStr++;
01646                 
01647                 // Close the adapter
01648                 PacketCloseAdapter(adapter);
01649                 
01650       } // for end - parse string
01651             *DpStr=0;
01652             
01653             pStr[k++]=0;
01654             pStr[k]=0;
01655             
01656             if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
01657                 memcpy(pStr+k,DescBuf,DpStr-DescBuf);
01658             else{
01659                 GlobalFreePtr(OidData);
01660                 GlobalFreePtr (BpStr);
01661                 GlobalFreePtr (DescBuf);
01662                 return FALSE;
01663             }
01664             
01665             GlobalFreePtr(OidData);
01666             GlobalFreePtr (BpStr);
01667             GlobalFreePtr (DescBuf);
01668             return TRUE;
01669     } // if key 'bind' was successfully opened
01670         else{
01671             MessageBox(NULL,TEXT("Can not find TCP/IP bindings.\nIn order to run the packet capture driver you must install TCP/IP."),szWindowTitle,MB_OK);
01672             ODS("Cannot find the TCP/IP bindings");
01673             return FALSE;
01674         }
01675     }
01676 }
01690 BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries)
01691 {
01692     char    *AdapterNameA;
01693     WCHAR   *AdapterNameU;
01694     WCHAR   *ifname;
01695     HKEY    SystemKey;
01696     HKEY    InterfaceKey;
01697     HKEY    ParametersKey;
01698     HKEY    TcpIpKey;
01699     HKEY    UnderTcpKey;
01700     LONG    status;
01701     WCHAR   String[1024+1];
01702     DWORD   RegType;
01703     ULONG   BufLen;
01704     DWORD   DHCPEnabled;
01705     struct  sockaddr_in *TmpAddr, *TmpBroad;
01706     LONG    naddrs,nmasks,StringPos;
01707     DWORD   ZeroBroadcast;
01708 
01709     AdapterNameA = (char*)AdapterName;
01710     if(AdapterNameA[1] != 0) {  //ASCII
01711         AdapterNameU = SChar2WChar(AdapterNameA);
01712         AdapterName = AdapterNameU;
01713     } else {                //Unicode
01714         AdapterNameU = NULL;
01715     }
01716     ifname = wcsrchr(AdapterName, '\\');
01717     if (ifname == NULL)
01718         ifname = AdapterName;
01719     else
01720         ifname++;
01721     if (wcsncmp(ifname, L"NPF_", 4) == 0)
01722         ifname += 4;
01723 
01724     if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
01725     {
01726         status = RegOpenKeyEx(UnderTcpKey,ifname,0,KEY_READ,&TcpIpKey);
01727         if (status != ERROR_SUCCESS) {
01728             RegCloseKey(UnderTcpKey);
01729             goto fail;
01730         }
01731     }
01732     else
01733     {
01734         
01735         // Query the registry key with the interface's adresses
01736         status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
01737         if (status != ERROR_SUCCESS)
01738             goto fail;
01739         status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
01740         if (status != ERROR_SUCCESS) {
01741             RegCloseKey(SystemKey);
01742             goto fail;
01743         }
01744         RegCloseKey(SystemKey);
01745         status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
01746         if (status != ERROR_SUCCESS) {
01747             RegCloseKey(InterfaceKey);
01748             goto fail;
01749         }
01750         RegCloseKey(InterfaceKey);
01751         status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
01752         if (status != ERROR_SUCCESS) {
01753             RegCloseKey(ParametersKey);
01754             goto fail;
01755         }
01756         RegCloseKey(ParametersKey);
01757         BufLen = sizeof String;
01758     }
01759 
01760     BufLen = 4;
01761     /* Try to detect if the interface has a zero broadcast addr */
01762     status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen);
01763     if (status != ERROR_SUCCESS)
01764         ZeroBroadcast=0;
01765     
01766     BufLen = 4;
01767     /* See if DHCP is used by this system */
01768     status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
01769     if (status != ERROR_SUCCESS)
01770         DHCPEnabled=0;
01771     
01772     
01773     /* Retrieve the adrresses */
01774     if(DHCPEnabled){
01775         
01776         BufLen = sizeof String;
01777         // Open the key with the addresses
01778         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
01779         if (status != ERROR_SUCCESS) {
01780             RegCloseKey(TcpIpKey);
01781             goto fail;
01782         }
01783 
01784         // scan the key to obtain the addresses
01785         StringPos = 0;
01786         for(naddrs = 0;naddrs <* NEntries;naddrs++){
01787             TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
01788             
01789             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01790                 TmpAddr->sin_family = AF_INET;
01791                 
01792                 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
01793                 TmpBroad->sin_family = AF_INET;
01794                 if(ZeroBroadcast==0)
01795                     TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
01796                 else
01797                     TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
01798 
01799                 while(*(String + StringPos) != 0)StringPos++;
01800                 StringPos++;
01801                 
01802                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01803                     break;              
01804             }
01805             else break;
01806         }       
01807         
01808         BufLen = sizeof String;
01809         // Open the key with the netmasks
01810         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
01811         if (status != ERROR_SUCCESS) {
01812             RegCloseKey(TcpIpKey);
01813             goto fail;
01814         }
01815         
01816         // scan the key to obtain the masks
01817         StringPos = 0;
01818         for(nmasks = 0;nmasks < *NEntries;nmasks++){
01819             TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
01820             
01821             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01822                 TmpAddr->sin_family = AF_INET;
01823                 
01824                 while(*(String + StringPos) != 0)StringPos++;
01825                 StringPos++;
01826                                 
01827                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01828                     break;
01829             }
01830             else break;
01831         }       
01832         
01833         // The number of masks MUST be equal to the number of adresses
01834         if(nmasks != naddrs){
01835             RegCloseKey(TcpIpKey);
01836             goto fail;
01837         }
01838                 
01839     }
01840     else{
01841         
01842         BufLen = sizeof String;
01843         // Open the key with the addresses
01844         status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
01845         if (status != ERROR_SUCCESS) {
01846             RegCloseKey(TcpIpKey);
01847             goto fail;
01848         }
01849         
01850         // scan the key to obtain the addresses
01851         StringPos = 0;
01852         for(naddrs = 0;naddrs < *NEntries;naddrs++){
01853             TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
01854             
01855             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01856                 TmpAddr->sin_family = AF_INET;
01857 
01858                 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
01859                 TmpBroad->sin_family = AF_INET;
01860                 if(ZeroBroadcast==0)
01861                     TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
01862                 else
01863                     TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
01864                 
01865                 while(*(String + StringPos) != 0)StringPos++;
01866                 StringPos++;
01867                 
01868                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01869                     break;
01870             }
01871             else break;
01872         }       
01873         
01874         BufLen = sizeof String;
01875         // Open the key with the netmasks
01876         status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
01877         if (status != ERROR_SUCCESS) {
01878             RegCloseKey(TcpIpKey);
01879             goto fail;
01880         }
01881         
01882         // scan the key to obtain the masks
01883         StringPos = 0;
01884         for(nmasks = 0;nmasks <* NEntries;nmasks++){
01885             TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
01886             
01887             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01888                 TmpAddr->sin_family = AF_INET;
01889                 
01890                 while(*(String + StringPos) != 0)StringPos++;
01891                 StringPos++;
01892                 
01893                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01894                     break;
01895             }
01896             else break;
01897         }       
01898         
01899         // The number of masks MUST be equal to the number of adresses
01900         if(nmasks != naddrs){
01901             RegCloseKey(TcpIpKey);
01902             goto fail;
01903         }
01904                 
01905     }
01906     
01907     *NEntries = naddrs + 1;
01908 
01909     RegCloseKey(TcpIpKey);
01910     
01911     if (status != ERROR_SUCCESS) {
01912         goto fail;
01913     }
01914     
01915     
01916     if (AdapterNameU != NULL)
01917         free(AdapterNameU);
01918     return TRUE;
01919     
01920 fail:
01921     if (AdapterNameU != NULL)
01922         free(AdapterNameU);
01923     return FALSE;
01924 }
01925 
01936 BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp)
01937 {
01938     char    *AdapterNameA;
01939     WCHAR   *AdapterNameU;
01940     WCHAR   *ifname;
01941     HKEY    SystemKey;
01942     HKEY    InterfaceKey;
01943     HKEY    ParametersKey;
01944     HKEY    TcpIpKey;
01945     LONG    status;
01946     WCHAR   String[1024+1];
01947     DWORD   RegType;
01948     ULONG   BufLen;
01949     DWORD   DHCPEnabled;
01950     ULONG   TAddr,i;
01951 
01952     AdapterNameA = (char*)AdapterName;
01953     if(AdapterNameA[1] != 0) {  //ASCII
01954         AdapterNameU = SChar2WChar(AdapterNameA);
01955         AdapterName = AdapterNameU;
01956     } else {                //Unicode
01957         AdapterNameU = NULL;
01958     }
01959     ifname = wcsrchr(AdapterName, '\\');
01960     if (ifname == NULL)
01961         ifname = AdapterName;
01962     else
01963         ifname++;
01964     if (wcsncmp(ifname, L"NPF_", 4) == 0)
01965         ifname += 4;
01966     status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
01967     if (status != ERROR_SUCCESS)
01968         goto fail;
01969     status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
01970     if (status != ERROR_SUCCESS) {
01971         RegCloseKey(SystemKey);
01972         goto fail;
01973     }
01974     RegCloseKey(SystemKey);
01975     status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
01976     if (status != ERROR_SUCCESS) {
01977         RegCloseKey(InterfaceKey);
01978         goto fail;
01979     }
01980     RegCloseKey(InterfaceKey);
01981     status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
01982     if (status != ERROR_SUCCESS) {
01983         RegCloseKey(ParametersKey);
01984         goto fail;
01985     }
01986     RegCloseKey(ParametersKey);
01987         
01988     BufLen = 4;
01989     /* See if DHCP is used by this system */
01990     status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
01991     if (status != ERROR_SUCCESS)
01992         DHCPEnabled=0;
01993 
01994     
01995     /* Retrieve the netmask */
01996     if(DHCPEnabled){
01997         
01998         BufLen = sizeof String;
01999         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
02000         if (status != ERROR_SUCCESS) {
02001             RegCloseKey(TcpIpKey);
02002             goto fail;
02003         }
02004 
02005         TAddr = inet_addrU(String);
02006         // swap bytes for backward compatibility
02007         for(i=0;i<4;i++){
02008             *((char*)netp+i) = *((char*)&TAddr+3-i);
02009         }
02010         
02011         BufLen = sizeof String;
02012         status=RegQueryValueEx(TcpIpKey,TEXT("DHCPSubnetMask"),NULL,&RegType,
02013             (LPBYTE)String,&BufLen);
02014         
02015         TAddr = inet_addrU(String);
02016         // swap bytes for backward compatibility
02017         for(i=0;i<4;i++){
02018             *((char*)maskp+i) = *((char*)&TAddr+3-i);
02019         }
02020     }
02021     else{
02022 
02023         BufLen = sizeof String;
02024         status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
02025         if (status != ERROR_SUCCESS) {
02026             RegCloseKey(TcpIpKey);
02027             goto fail;
02028         }
02029 
02030         TAddr = inet_addrU(String);
02031         // swap bytes for backward compatibility
02032         for(i=0;i<4;i++){
02033             *((char*)netp+i) = *((char*)&TAddr+3-i);
02034         }
02035         
02036         BufLen = sizeof String;
02037         status=RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,
02038             (LPBYTE)String,&BufLen);
02039         
02040         TAddr = inet_addrU(String);
02041         // swap bytes for backward compatibility
02042         for(i=0;i<4;i++){
02043             *((char*)maskp+i) = *((char*)&TAddr+3-i);
02044         }
02045 
02046 
02047     }
02048     
02049     RegCloseKey(TcpIpKey);  
02050         
02051     if (AdapterNameU != NULL)
02052         free(AdapterNameU);
02053     return TRUE;
02054     
02055 fail:
02056     if (AdapterNameU != NULL)
02057         free(AdapterNameU);
02058     return FALSE;
02059 }
02060 
02061 
02062 /* @} */

documentation. Copyright (c)2002-2003 Politecnico di Torino.
2005 translated by Telebusiness,Inc.
 All rights reserved.