Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

Packet32.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999 - 2003
00003  * NetGroup, Politecnico di Torino (Italy)
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  * notice, this list of conditions and the following disclaimer.
00012  * 2. Redistributions in binary form must reproduce the above copyright
00013  * notice, this list of conditions and the following disclaimer in the
00014  * documentation and/or other materials provided with the distribution.
00015  * 3. Neither the name of the Politecnico di Torino nor the names of its
00016  * contributors may be used to endorse or promote products derived from
00017  * this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00022  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00023  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00025  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00026  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00027  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00029  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  */
00032 
00033 #define UNICODE 1
00034 
00035 #include <packet32.h>
00036 
00037 #include <windows.h>
00038 #include <windowsx.h>
00039 
00040 #include <ntddndis.h>
00041 
00042 
00044 TCHAR   szWindowTitle[] = TEXT("PACKET.DLL");
00045 
00046 #if _DBG
00047 #define ODS(_x) OutputDebugString(TEXT(_x))
00048 #define ODSEx(_x, _y)
00049 #else
00050 #ifdef _DEBUG_TO_FILE
00051 #include <stdio.h>
00055 #define ODS(_x) { \
00056     FILE *f; \
00057     f = fopen("winpcap_debug.txt", "a"); \
00058     fprintf(f, "%s", _x); \
00059     fclose(f); \
00060 }
00061 
00065 #define ODSEx(_x, _y) { \
00066     FILE *f; \
00067     f = fopen("winpcap_debug.txt", "a"); \
00068     fprintf(f, _x, _y); \
00069     fclose(f); \
00070 }
00071 
00072 
00073 
00074 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName);
00075 #else
00076 #define ODS(_x)     
00077 #define ODSEx(_x, _y)
00078 #endif
00079 #endif
00080 
00081 //service handles
00082 SC_HANDLE scmHandle = NULL;
00083 SC_HANDLE srvHandle = NULL;
00084 LPCTSTR NPFServiceName = TEXT("NPF");
00085 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter");
00086 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF");
00087 LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\npf.sys");
00088 
00089 //---------------------------------------------------------------------------
00090 
00095 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
00096 {
00097     BOOLEAN Status=TRUE;
00098 
00099     switch ( Reason )
00100     {
00101     case DLL_PROCESS_ATTACH:
00102         
00103         ODS("************Packet32: DllMain************\n");
00104         
00105 #ifdef _DEBUG_TO_FILE
00106         // dump a bunch of registry keys useful for debug to file
00107         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
00108             "adapters.reg");
00109         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip",
00110             "tcpip.reg");
00111         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF",
00112             "npf.reg");
00113         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
00114             "services.reg");
00115 #endif
00116         break;
00117 
00118         case DLL_PROCESS_DETACH:
00119             break;
00120 
00121         default:
00122             break;
00123     }
00124 
00125     return Status;
00126 }
00127 
00134 WCHAR* SChar2WChar(char* string)
00135 {
00136     WCHAR* TmpStr;
00137     TmpStr=(WCHAR*) malloc ((strlen(string)+2)*sizeof(WCHAR));
00138 
00139     MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2));
00140 
00141     return TmpStr;
00142 }
00143 
00153 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
00154 {
00155     BOOLEAN    Status;
00156     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
00157     PPACKET_OID_DATA  OidData;
00158 
00159     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
00160     if (OidData == NULL) {
00161         ODS("PacketSetMaxLookaheadsize failed\n");
00162         return FALSE;
00163     }
00164 
00165     //set the size of the lookahead buffer to the maximum available by the the NIC driver
00166     OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
00167     OidData->Length=sizeof(ULONG);
00168     Status=PacketRequest(AdapterObject,FALSE,OidData);
00169     OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
00170     Status=PacketRequest(AdapterObject,TRUE,OidData);
00171     GlobalFreePtr(OidData);
00172     return Status;
00173 }
00174 
00185 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
00186 {
00187     DWORD BytesReturned;
00188     TCHAR EventName[39];
00189 
00190     // this tells the terminal service to retrieve the event from the global namespace
00191     wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
00192 
00193     // retrieve the name of the shared event from the driver
00194     if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE;
00195 
00196     EventName[20]=0; // terminate the string
00197 
00198     // open the shared event
00199     AdapterObject->ReadEvent=CreateEvent(NULL,
00200                                          TRUE,
00201                                          FALSE,
00202                                          EventName);
00203 
00204     // in NT4 "Global\" is not automatically ignored: try to use simply the event name
00205     if(GetLastError()!=ERROR_ALREADY_EXISTS){
00206         if(AdapterObject->ReadEvent != NULL)
00207             CloseHandle(AdapterObject->ReadEvent);
00208         
00209         // open the shared event
00210         AdapterObject->ReadEvent=CreateEvent(NULL,
00211             TRUE,
00212             FALSE,
00213             EventName+7);
00214     }   
00215 
00216     if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
00217         ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
00218         return FALSE;
00219     }
00220 
00221     AdapterObject->ReadTimeOut=0;
00222 
00223     return TRUE;
00224 }
00225 
00235 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle)
00236 {
00237     BOOL result = FALSE;
00238     ULONG err;
00239     
00240     ODS("installdriver\n");
00241     
00242     *srvHandle = CreateService(ascmHandle, 
00243         NPFServiceName,
00244         NPFServiceDesc,
00245         SERVICE_ALL_ACCESS,
00246         SERVICE_KERNEL_DRIVER,
00247         SERVICE_DEMAND_START,
00248         SERVICE_ERROR_NORMAL,
00249         NPFDriverPath,
00250         NULL, NULL, NULL, NULL, NULL);
00251     if (*srvHandle == NULL) 
00252     {
00253         if (GetLastError() == ERROR_SERVICE_EXISTS) 
00254         {
00255             //npf.sys already existed
00256             result = TRUE;
00257         }
00258     }
00259     else 
00260     {
00261         //Created service for npf.sys
00262         result = TRUE;
00263     }
00264     if (result == TRUE) 
00265         if (*srvHandle != NULL)
00266             CloseServiceHandle(*srvHandle);
00267 
00268     if(result == FALSE){
00269         err = GetLastError();
00270         if(err != 2)
00271             ODSEx("PacketInstallDriver failed, Error=%d\n",err);
00272     }
00273     return result;
00274     
00275 }
00276 
00286 ULONG inet_addrU(const WCHAR *cp)
00287 {
00288     ULONG val, part;
00289     WCHAR c;
00290     int i;
00291 
00292     val = 0;
00293     for (i = 0; i < 4; i++) {
00294         part = 0;
00295         while ((c = *cp++) != '\0' && c != '.') {
00296             if (c < '0' || c > '9')
00297                 return -1;
00298             part = part*10 + (c - '0');
00299         }
00300         if (part > 255)
00301             return -1;  
00302         val = val | (part << i*8);
00303         if (i == 3) {
00304             if (c != '\0')
00305                 return -1;  // extra gunk at end of string 
00306         } else {
00307             if (c == '\0')
00308                 return -1;  // string ends early 
00309         }
00310     }
00311     return val;
00312 }
00313 
00323 #ifdef _DEBUG_TO_FILE
00324 
00325 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
00326 {
00327     CHAR Command[256];
00328 
00329     strcpy(Command, "regedit /e ");
00330     strcat(Command, FileName);
00331     strcat(Command, " ");
00332     strcat(Command, KeyName);
00333 
00335     system(Command);
00336 
00337     return TRUE;
00338 }
00339 #endif
00340 
00341 //---------------------------------------------------------------------------
00342 // PUBLIC API
00343 //---------------------------------------------------------------------------
00344 
00353 
00354 char PacketLibraryVersion[] = "3.0.1 alpha"; 
00355 
00360 PCHAR PacketGetVersion(){
00361     return PacketLibraryVersion;
00362 }
00363 
00380 BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type)
00381 {
00382     BOOLEAN    Status;
00383     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
00384     PPACKET_OID_DATA  OidData;
00385 
00386     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
00387     if (OidData == NULL) {
00388         ODS("PacketGetNetType failed\n");
00389         return FALSE;
00390     }
00391     //get the link-layer type
00392     OidData->Oid = OID_GEN_MEDIA_IN_USE;
00393     OidData->Length = sizeof (ULONG);
00394     Status = PacketRequest(AdapterObject,FALSE,OidData);
00395     type->LinkType=*((UINT*)OidData->Data);
00396 
00397     //get the link-layer speed
00398     OidData->Oid = OID_GEN_LINK_SPEED;
00399     OidData->Length = sizeof (ULONG);
00400     Status = PacketRequest(AdapterObject,FALSE,OidData);
00401     type->LinkSpeed=*((UINT*)OidData->Data)*100;
00402     GlobalFreePtr (OidData);
00403 
00404     ODSEx("Media:%d ",type->LinkType);
00405     ODSEx("Speed=%d\n",type->LinkSpeed);
00406 
00407     return Status;
00408 }
00409 
00418 BOOL PacketStopDriver()
00419 {
00420     SC_HANDLE       scmHandle;
00421     SC_HANDLE       schService;
00422     BOOL            ret;
00423     SERVICE_STATUS  serviceStatus;
00424 
00425     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00426     
00427     if(scmHandle != NULL){
00428         
00429         schService = OpenService (scmHandle,
00430             NPFServiceName,
00431             SERVICE_ALL_ACCESS
00432             );
00433         
00434         if (schService != NULL)
00435         {
00436             
00437             ret = ControlService (schService,
00438                 SERVICE_CONTROL_STOP,
00439                 &serviceStatus
00440                 );
00441             if (!ret)
00442             {
00443             }
00444             
00445             CloseServiceHandle (schService);
00446             
00447             CloseServiceHandle(scmHandle);
00448             
00449             return ret;
00450         }
00451     }
00452     
00453     return FALSE;
00454 
00455 }
00456 
00479 LPADAPTER PacketOpenAdapter(LPTSTR AdapterName)
00480 {
00481     LPADAPTER lpAdapter;
00482     BOOLEAN Result;
00483     char *AdapterNameA;
00484     WCHAR *AdapterNameU;
00485     DWORD error;
00486     SC_HANDLE svcHandle = NULL;
00487     LONG KeyRes;
00488     HKEY PathKey;
00489     SERVICE_STATUS SStat;
00490     BOOLEAN QuerySStat;
00491     WCHAR SymbolicLink[128];
00492 
00493     ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName)
00494 
00495     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00496     
00497     if(scmHandle == NULL){
00498         error = GetLastError();
00499         ODSEx("OpenSCManager failed! Error=%d\n", error);
00500     }
00501     else{
00502         // check if the NPF registry key is already present
00503         // this means that the driver is already installed and that we don't need to call PacketInstallDriver
00504         KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00505             NPFRegistryLocation,
00506             0,
00507             KEY_READ,
00508             &PathKey);
00509         
00510         if(KeyRes != ERROR_SUCCESS)
00511         {
00512             Result = PacketInstallDriver(scmHandle,&svcHandle);
00513         }
00514         else
00515         {
00516             Result = TRUE;
00517             RegCloseKey(PathKey);
00518         }
00519         
00520         if (Result) 
00521         {
00522             
00523             srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
00524             if (srvHandle != NULL)
00525             {
00526                 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
00527                 ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
00528                 
00529                 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
00530                 {
00531                     ODS("Calling startservice\n");
00532                     if (StartService(srvHandle, 0, NULL)==0)
00533                     { 
00534                         error = GetLastError();
00535                         if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS)
00536                         {
00537                             SetLastError(error);
00538                             if (scmHandle != NULL) 
00539                                 CloseServiceHandle(scmHandle);
00540                             error = GetLastError();
00541                             ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
00542                             return NULL;
00543                         }
00544                     }               
00545                 }
00546 
00547                 CloseServiceHandle( srvHandle );
00548                 srvHandle = NULL;
00549 
00550             }
00551             else
00552             {
00553                 error = GetLastError();
00554                 ODSEx("OpenService failed! Error=%d", error);
00555             }
00556         }
00557         else
00558         {
00559             if(KeyRes != ERROR_SUCCESS)
00560                 Result = PacketInstallDriver(scmHandle,&svcHandle);
00561             else
00562                 Result = TRUE;
00563             
00564             if (Result) {
00565                 
00566                 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
00567                 if (srvHandle != NULL){
00568                     
00569                     QuerySStat = QueryServiceStatus(srvHandle, &SStat);
00570                     ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState);
00571                     
00572                     if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
00573                         
00574                         ODS("Calling startservice\n");
00575                         
00576                         if (StartService(srvHandle, 0, NULL)==0){ 
00577                             error = GetLastError();
00578                             if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
00579                                 SetLastError(error);
00580                                 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00581                                 ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error);
00582                                 return NULL;
00583                             }
00584                         }
00585                     }
00586                     
00587                     CloseServiceHandle( srvHandle );
00588                     srvHandle = NULL;
00589 
00590                 }
00591                 else{
00592                     error = GetLastError();
00593                     ODSEx("OpenService failed! Error=%d", error);
00594                 }
00595             }
00596         }
00597     }
00598 
00599     if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00600 
00601     AdapterNameA=(char*)AdapterName;
00602     if(AdapterNameA[1]!=0){ //ASCII
00603         AdapterNameU=SChar2WChar(AdapterNameA);
00604         AdapterName=AdapterNameU;
00605     } else {            //Unicode
00606         AdapterNameU=NULL;
00607     }
00608     
00609     lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER));
00610     if (lpAdapter==NULL)
00611     {
00612         ODS("PacketOpenAdapter: GlobalAlloc Failed\n");
00613         error=GetLastError();
00614         if (AdapterNameU != NULL) free(AdapterNameU);
00615         //set the error to the one on which we failed
00616         SetLastError(error);
00617         ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n");
00618         return NULL;
00619     }
00620     lpAdapter->NumWrites=1;
00621 
00622 
00623 
00624     if (LOWORD(GetVersion()) == 4)
00625         wsprintf(SymbolicLink,TEXT("\\\\.\\%s"),&AdapterName[8]);
00626     else
00627         wsprintf(SymbolicLink,TEXT("\\\\.\\Global\\%s"),&AdapterName[8]);
00628     
00629     // Copy  only the bytes that fit in the adapter structure.
00630     // Note that lpAdapter->SymbolicLink is present for backward compatibility but will
00631     // never be used by the apps
00632     memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
00633 
00634     //try if it is possible to open the adapter immediately
00635     lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
00636         0,NULL,OPEN_EXISTING,0,0);
00637     
00638     if (lpAdapter->hFile != INVALID_HANDLE_VALUE) 
00639     {
00640 
00641         if(PacketSetReadEvt(lpAdapter)==FALSE){
00642             error=GetLastError();
00643             ODS("PacketOpenAdapter: Unable to open the read event\n");
00644             if (AdapterNameU != NULL)
00645                 free(AdapterNameU);
00646             GlobalFreePtr(lpAdapter);
00647             //set the error to the one on which we failed
00648             SetLastError(error);
00649             ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error);
00650             return NULL;
00651         }       
00652         
00653         PacketSetMaxLookaheadsize(lpAdapter);
00654         if (AdapterNameU != NULL)
00655             free(AdapterNameU);
00656         return lpAdapter;
00657     }
00658 
00659 
00660     error=GetLastError();
00661     if (AdapterNameU != NULL)
00662         free(AdapterNameU);
00663     GlobalFreePtr(lpAdapter);
00664     //set the error to the one on which we failed
00665     SetLastError(error);
00666     ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error);
00667     return NULL;
00668 
00669 }
00670 
00677 VOID PacketCloseAdapter(LPADAPTER lpAdapter)
00678 {
00679     CloseHandle(lpAdapter->hFile);
00680     SetEvent(lpAdapter->ReadEvent);
00681     CloseHandle(lpAdapter->ReadEvent);
00682     GlobalFreePtr(lpAdapter);
00683 }
00684 
00697 LPPACKET PacketAllocatePacket(void)
00698 {
00699 
00700     LPPACKET    lpPacket;
00701     lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
00702     if (lpPacket==NULL)
00703     {
00704         ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
00705         return NULL;
00706     }
00707     return lpPacket;
00708 }
00709 
00718 VOID PacketFreePacket(LPPACKET lpPacket)
00719 
00720 {
00721     GlobalFreePtr(lpPacket);
00722 }
00723 
00740 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)
00741 
00742 {
00743     lpPacket->Buffer = Buffer;
00744     lpPacket->Length = Length;
00745     lpPacket->ulBytesReceived = 0;
00746     lpPacket->bIoComplete = FALSE;
00747 }
00748 
00779 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
00780 {
00781     BOOLEAN res;
00782 
00783     if((int)AdapterObject->ReadTimeOut != -1)
00784         WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
00785 
00786     res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
00787 
00788     return res;
00789 }
00790 
00820 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
00821 
00822 {
00823     DWORD        BytesTransfered;
00824     
00825     return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
00826 }
00827 
00828 
00856 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
00857 {
00858     BOOLEAN         Res;
00859     DWORD           BytesTransfered, TotBytesTransfered=0;
00860     struct timeval  BufStartTime;
00861     LARGE_INTEGER   StartTicks, CurTicks, TargetTicks, TimeFreq;
00862 
00863     ODS("PacketSendPackets");
00864 
00865     // Obtain starting timestamp of the buffer
00866     BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec;
00867     BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
00868 
00869     // Retrieve the reference time counters
00870     QueryPerformanceCounter(&StartTicks);
00871     QueryPerformanceFrequency(&TimeFreq);
00872 
00873     CurTicks.QuadPart = StartTicks.QuadPart;
00874 
00875     do{
00876         // Send the data to the driver
00877         Res = DeviceIoControl(AdapterObject->hFile,
00878             (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC,
00879             (PCHAR)PacketBuff + TotBytesTransfered,
00880             Size - TotBytesTransfered,
00881             NULL,
00882             0,
00883             &BytesTransfered,
00884             NULL);
00885 
00886         TotBytesTransfered += BytesTransfered;
00887 
00888         // Exit from the loop on termination or error
00889         if(TotBytesTransfered >= Size || Res != TRUE)
00890             break;
00891         
00892         if(Sync){
00893 
00894             // calculate the time interval to wait before sending the next packet
00895             TargetTicks.QuadPart = StartTicks.QuadPart +
00896                 (LONGLONG)
00897                 ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 +
00898                 (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *
00899                 (TimeFreq.QuadPart) / 1000000;
00900 
00901             // Wait until the time interval has elapsed
00902             while( CurTicks.QuadPart <= TargetTicks.QuadPart ){
00903                 QueryPerformanceCounter(&CurTicks);
00904             }
00905         }
00906     }
00907     while(TRUE);
00908 
00909     return TotBytesTransfered;
00910 }
00911 
00930 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
00931 {
00932     DWORD BytesReturned;
00933     return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
00934 }
00935 
00972 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
00973 {
00974     DWORD BytesReturned;
00975 
00976     return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
00977 }
00978 
00993 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len)
00994 {
00995     DWORD       BytesReturned;
00996     WCHAR   *FileName;
00997     BOOLEAN res;
00998     WCHAR   NameWithPath[1024];
00999     int     TStrLen;
01000     WCHAR   *NamePos;
01001 
01002     if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII
01003         FileName=SChar2WChar(name);
01004         len*=2;
01005     } 
01006     else {  //Unicode
01007         FileName=name;
01008     }
01009 
01010     TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos);
01011 
01012     len=TStrLen*2+2;  //add the terminating null character
01013 
01014     // Try to catch malformed strings
01015     if(len>2048){
01016         if(((PUCHAR)name)[1]!=0 && len>1) free(FileName);
01017         return FALSE;
01018     }
01019 
01020     res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL);
01021     free(FileName);
01022     return res;
01023 }
01024 
01040 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks)
01041 {
01042     DWORD       BytesReturned;
01043     UINT valbuff[2];
01044 
01045     valbuff[0] = maxfilesize;
01046     valbuff[1] = maxnpacks;
01047 
01048     return DeviceIoControl(AdapterObject->hFile,
01049         pBIOCSETDUMPLIMITS,
01050         valbuff,
01051         sizeof valbuff,
01052         NULL,
01053         0,
01054         &BytesReturned,
01055         NULL);  
01056 }
01057 
01071 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
01072 {
01073     DWORD       BytesReturned;
01074     int     IsDumpEnded;
01075     BOOLEAN res;
01076 
01077     if(sync)
01078         WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
01079 
01080     res = DeviceIoControl(AdapterObject->hFile,
01081         pBIOCISDUMPENDED,
01082         NULL,
01083         0,
01084         &IsDumpEnded,
01085         4,
01086         &BytesReturned,
01087         NULL);
01088 
01089     if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished
01090 
01091     return (BOOLEAN)IsDumpEnded;
01092 }
01093 
01113 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
01114 {
01115     return AdapterObject->ReadEvent;
01116 }
01117 
01126 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
01127 {
01128     DWORD BytesReturned;
01129     return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
01130 }
01131 
01144 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
01145 {
01146     DWORD BytesReturned;
01147     int DriverTimeOut=-1;
01148 
01149     AdapterObject->ReadTimeOut=timeout;
01150 
01151     return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
01152 }
01153 
01170 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
01171 {
01172     DWORD BytesReturned;
01173     return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
01174 }
01175 
01196 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp)
01197 {
01198     DWORD BytesReturned;
01199     return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
01200 }
01201 
01215 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
01216 {
01217     BOOLEAN Res;
01218     DWORD BytesReturned;
01219     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
01220 
01221     Res = DeviceIoControl(AdapterObject->hFile,
01222         pBIOCGSTATS,
01223         NULL,
01224         0,
01225         &tmpstat,
01226         sizeof(struct bpf_stat),
01227         &BytesReturned,
01228         NULL);
01229 
01230     // Copy only the first two values retrieved from the driver
01231     s->bs_recv = tmpstat.bs_recv;
01232     s->bs_drop = tmpstat.bs_drop;
01233 
01234     return Res;
01235 }
01236 
01249 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
01250 {
01251     BOOLEAN Res;
01252     DWORD BytesReturned;
01253     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
01254 
01255     Res = DeviceIoControl(AdapterObject->hFile,
01256         pBIOCGSTATS,
01257         NULL,
01258         0,
01259         &tmpstat,
01260         sizeof(struct bpf_stat),
01261         &BytesReturned,
01262         NULL);
01263 
01264     s->bs_recv = tmpstat.bs_recv;
01265     s->bs_drop = tmpstat.bs_drop;
01266     s->ps_ifdrop = tmpstat.ps_ifdrop;
01267     s->bs_capt = tmpstat.bs_capt;
01268 
01269     return Res;
01270 }
01271 
01284 BOOLEAN PacketRequest(LPADAPTER  AdapterObject,BOOLEAN Set,PPACKET_OID_DATA  OidData)
01285 {
01286     DWORD       BytesReturned;
01287     BOOLEAN     Result;
01288 
01289     Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID,
01290                            OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
01291                            sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);
01292     
01293     // output some debug info
01294     ODSEx("PacketRequest, OID=%d ", OidData->Oid);
01295     ODSEx("Length=%d ", OidData->Length);
01296     ODSEx("Set=%d ", Set);
01297     ODSEx("Res=%d\n", Result);
01298 
01299     return Result;
01300 }
01301 
01318 BOOLEAN PacketSetHwFilter(LPADAPTER  AdapterObject,ULONG Filter)
01319 {
01320     BOOLEAN    Status;
01321     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
01322     PPACKET_OID_DATA  OidData;
01323 
01324     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
01325     if (OidData == NULL) {
01326         ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
01327         return FALSE;
01328     }
01329     OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
01330     OidData->Length=sizeof(ULONG);
01331     *((PULONG)OidData->Data)=Filter;
01332     Status=PacketRequest(AdapterObject,TRUE,OidData);
01333     GlobalFreePtr(OidData);
01334     return Status;
01335 }
01336 
01366 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG  BufferSize)
01367 {
01368   HKEY      LinkageKey,AdapKey, OneAdapKey;
01369     DWORD       RegKeySize=0;
01370   LONG      Status;
01371     ULONG       Result;
01372     PTSTR       BpStr;
01373     char        *TTpStr,*DpStr,*DescBuf;
01374     LPADAPTER   adapter;
01375   PPACKET_OID_DATA  OidData;
01376     int         i=0,k,rewind;
01377     DWORD       dim;
01378     TCHAR       AdapName[256];
01379 
01380   ODSEx("PacketGetAdapterNames: BufferSize=%d\n",*BufferSize);
01381 
01382   OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,512);
01383   if (OidData == NULL) {
01384       ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
01385       return FALSE;
01386   }
01387 
01388   Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
01389                       TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"),
01390                         0,
01391                         KEY_READ,
01392                         &AdapKey);
01393   if ( Status != ERROR_SUCCESS ){
01394     ODS("PacketGetAdapterNames: RegOpenKeyEx ( Class\{networkclassguid} ) Failed\n");
01395     return FALSE;
01396   }
01397 
01398     // Get the size to allocate for the original device names
01399     while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
01400     {
01401         Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&OneAdapKey);
01402         if ( Status != ERROR_SUCCESS )
01403         {
01404             RegCloseKey(AdapKey);
01405             ODS("PacketGetAdapterNames: RegOpenKeyEx ( OneAdapKey ) Failed\n");
01406             i++;
01407             continue;
01408         }
01409     
01410         Status=RegOpenKeyEx(OneAdapKey,L"Linkage",0,KEY_READ,&LinkageKey);
01411         if ( Status != ERROR_SUCCESS )
01412         {
01413             RegCloseKey( OneAdapKey );
01414             RegCloseKey(AdapKey);
01415             ODS("PacketGetAdapterNames: RegOpenKeyEx ( LinkageKey ) Failed\n");
01416             i++;
01417             continue;
01418         }
01419 
01420         Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,NULL,&dim);
01421 
01422         RegCloseKey( OneAdapKey );
01423         RegCloseKey( LinkageKey );
01424 
01425         i++;
01426         if(Status!=ERROR_SUCCESS) continue;
01427         RegKeySize+=dim;
01428     } // while enum reg key still find keys
01429     
01430     // Allocate the memory for the original device names
01431     ODSEx("Need %d bytes for the names\n", RegKeySize+2);
01432     BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
01433     if (BpStr == NULL || RegKeySize > *BufferSize) {
01434         ODS("PacketGetAdapterNames: GlobalAlloc Failed\n");
01435         GlobalFreePtr(OidData);
01436         return FALSE;
01437     }
01438 
01439     k=0;
01440     i=0;
01441 
01442   ODS("PacketGetAdapterNames: Cycling through the adapters:\n");
01443 
01444     // Copy the names to the buffer
01445     while((Result=RegEnumKey(AdapKey,i,AdapName,sizeof(AdapName)/2))==ERROR_SUCCESS)
01446     {
01447         WCHAR UpperBindStr[64];
01448 
01449         i++;
01450         ODSEx(" %d) ", i);
01451 
01452         Status=RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&OneAdapKey);
01453     if ( Status != ERROR_SUCCESS ){
01454         RegCloseKey(AdapKey);
01455       ODS("PacketGetAdapterNames: RegOpenKeyEx ( OneAdapKey ) Failed\n");
01456       return FALSE;
01457     }
01458         Status=RegOpenKeyEx(OneAdapKey,L"Linkage",0,KEY_READ,&LinkageKey);
01459     if ( Status != ERROR_SUCCESS ){
01460       RegCloseKey( OneAdapKey );
01461         RegCloseKey(AdapKey);
01462       ODS("PacketGetAdapterNames: RegOpenKeyEx ( LinkageKey ) Failed\n");
01463       return FALSE;
01464     }
01465 
01466         dim=sizeof(UpperBindStr);
01467         Status=RegQueryValueEx(LinkageKey,L"UpperBind",NULL,NULL,(PUCHAR)UpperBindStr,&dim);
01468         
01469         ODSEx("UpperBind=%S ", UpperBindStr);
01470 
01471         dim=RegKeySize-k;
01472         Status=RegQueryValueEx(LinkageKey,L"Export",NULL,NULL,(LPBYTE)BpStr+k,&dim);
01473         if(Status!=ERROR_SUCCESS){
01474       RegCloseKey( OneAdapKey );
01475       RegCloseKey( LinkageKey );
01476             ODS("Name = SKIPPED (error reading the key)\n");
01477             continue;
01478         }
01479 
01480     RegCloseKey( OneAdapKey );
01481     RegCloseKey( LinkageKey );
01482         ODSEx("Name = %S\n", (LPBYTE)BpStr+k);
01483 
01484         k+=dim-2;
01485   } // while enum reg keys
01486 
01487     RegCloseKey(AdapKey);
01488 
01489 #ifdef _DEBUG_TO_FILE
01490     //dump BpStr for debug purposes
01491     ODS("Dumping BpStr:");
01492     {
01493         FILE *f;
01494         f = fopen("winpcap_debug.txt", "a");
01495         for(i=0;i<k;i++){
01496             if(!(i%32))fprintf(f, "\n ");
01497             fprintf(f, "%c " , *((LPBYTE)BpStr+i));
01498         }
01499         fclose(f);
01500     }
01501     ODS("\n");
01502 #endif
01503 
01504     
01505     if (k != 0)
01506   {
01507     DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
01508 
01509         if (DescBuf == NULL) {
01510             GlobalFreePtr (BpStr);
01511           GlobalFreePtr(OidData);
01512             return FALSE;
01513         }
01514         DpStr=DescBuf;
01515                 
01516         for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;)
01517     {
01518             
01519             if(k+wcslen(BpStr+i)+30 > *BufferSize){
01520                 // Input buffer too small
01521                 GlobalFreePtr(OidData);
01522                 GlobalFreePtr (BpStr);
01523                 GlobalFreePtr (DescBuf);
01524                 ODS("PacketGetAdapterNames: Input buffer too small!\n");
01525                 return FALSE;
01526             }
01527 
01528             // Create the device name
01529             rewind=k;
01530             memcpy(pStr+k,BpStr+i,16);
01531             memcpy(pStr+k+8,TEXT("NPF_"),8);
01532             i+=8;
01533             k+=12;
01534             while(BpStr[i-1]!=0){
01535                 pStr[k++]=BpStr[i++];
01536             }
01537 
01538             // Open the adapter
01539             adapter=PacketOpenAdapter(pStr+rewind);
01540             if(adapter==NULL){
01541                 k=rewind;
01542                 continue;
01543             }
01544 
01545             // Retrieve the description
01546             OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
01547             OidData->Length = 256;
01548             ZeroMemory(OidData->Data,256);
01549             Status = PacketRequest(adapter,FALSE,OidData);
01550             if(Status==0 || ((char*)OidData->Data)[0]==0){
01551                 k=rewind;
01552                 continue;
01553             }
01554 
01555             ODSEx("Adapter Description=%s\n\n",OidData->Data);
01556 
01557             // Copy the description
01558             TTpStr=(char*)(OidData->Data);
01559             while(*TTpStr!=0){
01560                 *DpStr++=*TTpStr++;
01561             }
01562             *DpStr++=*TTpStr++;
01563             
01564             // Close the adapter
01565             PacketCloseAdapter(adapter);
01566             
01567     } // for end - parse through string
01568         *DpStr=0;
01569 
01570         pStr[k++]=0;
01571         pStr[k]=0;
01572 
01573         if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
01574             memcpy(pStr+k,DescBuf,DpStr-DescBuf);
01575         else{
01576           GlobalFreePtr(OidData);
01577             GlobalFreePtr (BpStr);
01578             GlobalFreePtr (DescBuf);
01579             ODS("\nPacketGetAdapterNames: ended with failure\n");
01580             return FALSE;
01581         }
01582 
01583       GlobalFreePtr(OidData);
01584         GlobalFreePtr (BpStr);
01585         GlobalFreePtr (DescBuf);
01586         ODS("\nPacketGetAdapterNames: ended correctly\n");
01587         return TRUE;
01588   } // if k != 0
01589     else{
01590       DWORD      RegType;
01591 
01592         ODS("Adapters not found under SYSTEM\\CurrentControlSet\\Control\\Class. Using the TCP/IP bindings.\n");
01593 
01594         GlobalFreePtr (BpStr);
01595 
01596         Status=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage"),0,KEY_READ,&LinkageKey);
01597         if (Status == ERROR_SUCCESS)
01598         {
01599             // Retrieve the length of the key
01600             Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,NULL,&RegKeySize);
01601             // Allocate the buffer
01602             BpStr=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,RegKeySize+2);
01603             if (BpStr == NULL || RegKeySize > *BufferSize) {
01604                 GlobalFreePtr(OidData);
01605                 return FALSE;
01606             }
01607             Status=RegQueryValueEx(LinkageKey,TEXT("bind"),NULL,&RegType,(LPBYTE)BpStr,&RegKeySize);
01608             RegCloseKey(LinkageKey);
01609         }
01610         
01611         if (Status==ERROR_SUCCESS){
01612             
01613             DescBuf=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096);
01614             if (DescBuf == NULL) {
01615                 GlobalFreePtr (BpStr);
01616                 GlobalFreePtr(OidData);
01617                 return FALSE;
01618             }
01619             DpStr=DescBuf;
01620             
01621             for(i=0,k=0;BpStr[i]!=0 || BpStr[i+1]!=0;){
01622                 
01623                 if(k+wcslen(BpStr+i)+30 > *BufferSize){
01624                     // Input buffer too small
01625                     GlobalFreePtr(OidData);
01626                     GlobalFreePtr (BpStr);
01627                     GlobalFreePtr (DescBuf);
01628                     return FALSE;
01629                 }
01630                 
01631                 // Create the device name
01632                 rewind=k;
01633                 memcpy(pStr+k,BpStr+i,16);
01634                 memcpy(pStr+k+8,TEXT("NPF_"),8);
01635                 i+=8;
01636                 k+=12;
01637                 while(BpStr[i-1]!=0){
01638                     pStr[k++]=BpStr[i++];
01639                 }
01640                 
01641                 // Open the adapter
01642                 adapter=PacketOpenAdapter(pStr+rewind);
01643                 if(adapter==NULL){
01644                     k=rewind;
01645                     continue;
01646                 }
01647                 
01648                 // Retrieve the description
01649                 OidData->Oid = OID_GEN_VENDOR_DESCRIPTION;
01650                 OidData->Length = 256;
01651                 Status = PacketRequest(adapter,FALSE,OidData);
01652                 if(Status==0 || ((char*)OidData->Data)[0]==0){
01653                     k=rewind;
01654                     continue;
01655                 }
01656                 
01657                 // Copy the description
01658                 TTpStr=(char*)(OidData->Data);
01659                 while(*TTpStr!=0){
01660                     *DpStr++=*TTpStr++;
01661                 }
01662                 *DpStr++=*TTpStr++;
01663                 
01664                 // Close the adapter
01665                 PacketCloseAdapter(adapter);
01666                 
01667       } // for end - parse string
01668             *DpStr=0;
01669             
01670             pStr[k++]=0;
01671             pStr[k]=0;
01672             
01673             if((ULONG)(DpStr-DescBuf+k) < *BufferSize)
01674                 memcpy(pStr+k,DescBuf,DpStr-DescBuf);
01675             else{
01676                 GlobalFreePtr(OidData);
01677                 GlobalFreePtr (BpStr);
01678                 GlobalFreePtr (DescBuf);
01679                 return FALSE;
01680             }
01681             
01682             GlobalFreePtr(OidData);
01683             GlobalFreePtr (BpStr);
01684             GlobalFreePtr (DescBuf);
01685             return TRUE;
01686     } // if key 'bind' was successfully opened
01687         else{
01688             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);
01689             ODS("Cannot find the TCP/IP bindings");
01690             return FALSE;
01691         }
01692     }
01693 }
01707 BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries)
01708 {
01709     char    *AdapterNameA;
01710     WCHAR   *AdapterNameU;
01711     WCHAR   *ifname;
01712     HKEY    SystemKey;
01713     HKEY    InterfaceKey;
01714     HKEY    ParametersKey;
01715     HKEY    TcpIpKey;
01716     HKEY    UnderTcpKey;
01717     LONG    status;
01718     WCHAR   String[1024+1];
01719     DWORD   RegType;
01720     ULONG   BufLen;
01721     DWORD   DHCPEnabled;
01722     struct  sockaddr_in *TmpAddr, *TmpBroad;
01723     LONG    naddrs,nmasks,StringPos;
01724     DWORD   ZeroBroadcast;
01725 
01726     AdapterNameA = (char*)AdapterName;
01727     if(AdapterNameA[1] != 0) {  //ASCII
01728         AdapterNameU = SChar2WChar(AdapterNameA);
01729         AdapterName = AdapterNameU;
01730     } else {                //Unicode
01731         AdapterNameU = NULL;
01732     }
01733     ifname = wcsrchr(AdapterName, '\\');
01734     if (ifname == NULL)
01735         ifname = AdapterName;
01736     else
01737         ifname++;
01738     if (wcsncmp(ifname, L"NPF_", 4) == 0)
01739         ifname += 4;
01740 
01741     if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces"), 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS)
01742     {
01743         status = RegOpenKeyEx(UnderTcpKey,ifname,0,KEY_READ,&TcpIpKey);
01744         if (status != ERROR_SUCCESS) {
01745             RegCloseKey(UnderTcpKey);
01746             goto fail;
01747         }
01748     }
01749     else
01750     {
01751         
01752         // Query the registry key with the interface's adresses
01753         status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
01754         if (status != ERROR_SUCCESS)
01755             goto fail;
01756         status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
01757         if (status != ERROR_SUCCESS) {
01758             RegCloseKey(SystemKey);
01759             goto fail;
01760         }
01761         RegCloseKey(SystemKey);
01762         status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
01763         if (status != ERROR_SUCCESS) {
01764             RegCloseKey(InterfaceKey);
01765             goto fail;
01766         }
01767         RegCloseKey(InterfaceKey);
01768         status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
01769         if (status != ERROR_SUCCESS) {
01770             RegCloseKey(ParametersKey);
01771             goto fail;
01772         }
01773         RegCloseKey(ParametersKey);
01774         BufLen = sizeof String;
01775     }
01776 
01777     BufLen = 4;
01778     /* Try to detect if the interface has a zero broadcast addr */
01779     status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen);
01780     if (status != ERROR_SUCCESS)
01781         ZeroBroadcast=0;
01782     
01783     BufLen = 4;
01784     /* See if DHCP is used by this system */
01785     status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
01786     if (status != ERROR_SUCCESS)
01787         DHCPEnabled=0;
01788     
01789     
01790     /* Retrieve the adrresses */
01791     if(DHCPEnabled){
01792         
01793         BufLen = sizeof String;
01794         // Open the key with the addresses
01795         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
01796         if (status != ERROR_SUCCESS) {
01797             RegCloseKey(TcpIpKey);
01798             goto fail;
01799         }
01800 
01801         // scan the key to obtain the addresses
01802         StringPos = 0;
01803         for(naddrs = 0;naddrs <* NEntries;naddrs++){
01804             TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
01805             
01806             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01807                 TmpAddr->sin_family = AF_INET;
01808                 
01809                 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
01810                 TmpBroad->sin_family = AF_INET;
01811                 if(ZeroBroadcast==0)
01812                     TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
01813                 else
01814                     TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
01815 
01816                 while(*(String + StringPos) != 0)StringPos++;
01817                 StringPos++;
01818                 
01819                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01820                     break;              
01821             }
01822             else break;
01823         }       
01824         
01825         BufLen = sizeof String;
01826         // Open the key with the netmasks
01827         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
01828         if (status != ERROR_SUCCESS) {
01829             RegCloseKey(TcpIpKey);
01830             goto fail;
01831         }
01832         
01833         // scan the key to obtain the masks
01834         StringPos = 0;
01835         for(nmasks = 0;nmasks < *NEntries;nmasks++){
01836             TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
01837             
01838             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01839                 TmpAddr->sin_family = AF_INET;
01840                 
01841                 while(*(String + StringPos) != 0)StringPos++;
01842                 StringPos++;
01843                                 
01844                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01845                     break;
01846             }
01847             else break;
01848         }       
01849         
01850         // The number of masks MUST be equal to the number of adresses
01851         if(nmasks != naddrs){
01852             RegCloseKey(TcpIpKey);
01853             goto fail;
01854         }
01855                 
01856     }
01857     else{
01858         
01859         BufLen = sizeof String;
01860         // Open the key with the addresses
01861         status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
01862         if (status != ERROR_SUCCESS) {
01863             RegCloseKey(TcpIpKey);
01864             goto fail;
01865         }
01866         
01867         // scan the key to obtain the addresses
01868         StringPos = 0;
01869         for(naddrs = 0;naddrs < *NEntries;naddrs++){
01870             TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress);
01871             
01872             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01873                 TmpAddr->sin_family = AF_INET;
01874 
01875                 TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast);
01876                 TmpBroad->sin_family = AF_INET;
01877                 if(ZeroBroadcast==0)
01878                     TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255
01879                 else
01880                     TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0
01881                 
01882                 while(*(String + StringPos) != 0)StringPos++;
01883                 StringPos++;
01884                 
01885                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01886                     break;
01887             }
01888             else break;
01889         }       
01890         
01891         BufLen = sizeof String;
01892         // Open the key with the netmasks
01893         status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen);
01894         if (status != ERROR_SUCCESS) {
01895             RegCloseKey(TcpIpKey);
01896             goto fail;
01897         }
01898         
01899         // scan the key to obtain the masks
01900         StringPos = 0;
01901         for(nmasks = 0;nmasks <* NEntries;nmasks++){
01902             TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask);
01903             
01904             if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){
01905                 TmpAddr->sin_family = AF_INET;
01906                 
01907                 while(*(String + StringPos) != 0)StringPos++;
01908                 StringPos++;
01909                 
01910                 if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen)
01911                     break;
01912             }
01913             else break;
01914         }       
01915         
01916         // The number of masks MUST be equal to the number of adresses
01917         if(nmasks != naddrs){
01918             RegCloseKey(TcpIpKey);
01919             goto fail;
01920         }
01921                 
01922     }
01923     
01924     *NEntries = naddrs + 1;
01925 
01926     RegCloseKey(TcpIpKey);
01927     
01928     if (status != ERROR_SUCCESS) {
01929         goto fail;
01930     }
01931     
01932     
01933     if (AdapterNameU != NULL)
01934         free(AdapterNameU);
01935     return TRUE;
01936     
01937 fail:
01938     if (AdapterNameU != NULL)
01939         free(AdapterNameU);
01940     return FALSE;
01941 }
01942 
01953 BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp)
01954 {
01955     char    *AdapterNameA;
01956     WCHAR   *AdapterNameU;
01957     WCHAR   *ifname;
01958     HKEY    SystemKey;
01959     HKEY    InterfaceKey;
01960     HKEY    ParametersKey;
01961     HKEY    TcpIpKey;
01962     LONG    status;
01963     WCHAR   String[1024+1];
01964     DWORD   RegType;
01965     ULONG   BufLen;
01966     DWORD   DHCPEnabled;
01967     ULONG   TAddr,i;
01968 
01969     AdapterNameA = (char*)AdapterName;
01970     if(AdapterNameA[1] != 0) {  //ASCII
01971         AdapterNameU = SChar2WChar(AdapterNameA);
01972         AdapterName = AdapterNameU;
01973     } else {                //Unicode
01974         AdapterNameU = NULL;
01975     }
01976     ifname = wcsrchr(AdapterName, '\\');
01977     if (ifname == NULL)
01978         ifname = AdapterName;
01979     else
01980         ifname++;
01981     if (wcsncmp(ifname, L"NPF_", 4) == 0)
01982         ifname += 4;
01983     status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SYSTEM\\CurrentControlSet\\Services"),0,KEY_READ,&SystemKey);
01984     if (status != ERROR_SUCCESS)
01985         goto fail;
01986     status = RegOpenKeyEx(SystemKey,ifname,0,KEY_READ,&InterfaceKey);
01987     if (status != ERROR_SUCCESS) {
01988         RegCloseKey(SystemKey);
01989         goto fail;
01990     }
01991     RegCloseKey(SystemKey);
01992     status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey);
01993     if (status != ERROR_SUCCESS) {
01994         RegCloseKey(InterfaceKey);
01995         goto fail;
01996     }
01997     RegCloseKey(InterfaceKey);
01998     status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey);
01999     if (status != ERROR_SUCCESS) {
02000         RegCloseKey(ParametersKey);
02001         goto fail;
02002     }
02003     RegCloseKey(ParametersKey);
02004         
02005     BufLen = 4;
02006     /* See if DHCP is used by this system */
02007     status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen);
02008     if (status != ERROR_SUCCESS)
02009         DHCPEnabled=0;
02010 
02011     
02012     /* Retrieve the netmask */
02013     if(DHCPEnabled){
02014         
02015         BufLen = sizeof String;
02016         status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
02017         if (status != ERROR_SUCCESS) {
02018             RegCloseKey(TcpIpKey);
02019             goto fail;
02020         }
02021 
02022         TAddr = inet_addrU(String);
02023         // swap bytes for backward compatibility
02024         for(i=0;i<4;i++){
02025             *((char*)netp+i) = *((char*)&TAddr+3-i);
02026         }
02027         
02028         BufLen = sizeof String;
02029         status=RegQueryValueEx(TcpIpKey,TEXT("DHCPSubnetMask"),NULL,&RegType,
02030             (LPBYTE)String,&BufLen);
02031         
02032         TAddr = inet_addrU(String);
02033         // swap bytes for backward compatibility
02034         for(i=0;i<4;i++){
02035             *((char*)maskp+i) = *((char*)&TAddr+3-i);
02036         }
02037     }
02038     else{
02039 
02040         BufLen = sizeof String;
02041         status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen);
02042         if (status != ERROR_SUCCESS) {
02043             RegCloseKey(TcpIpKey);
02044             goto fail;
02045         }
02046 
02047         TAddr = inet_addrU(String);
02048         // swap bytes for backward compatibility
02049         for(i=0;i<4;i++){
02050             *((char*)netp+i) = *((char*)&TAddr+3-i);
02051         }
02052         
02053         BufLen = sizeof String;
02054         status=RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,
02055             (LPBYTE)String,&BufLen);
02056         
02057         TAddr = inet_addrU(String);
02058         // swap bytes for backward compatibility
02059         for(i=0;i<4;i++){
02060             *((char*)maskp+i) = *((char*)&TAddr+3-i);
02061         }
02062 
02063 
02064     }
02065     
02066     RegCloseKey(TcpIpKey);  
02067         
02068     if (AdapterNameU != NULL)
02069         free(AdapterNameU);
02070     return TRUE;
02071     
02072 fail:
02073     if (AdapterNameU != NULL)
02074         free(AdapterNameU);
02075     return FALSE;
02076 }
02077 
02078 
02079 /* @} */

documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.