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  *  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 <stdio.h>
00025 #include <packet32.h>
00026 #include "wanpacket/wanpacket.h"
00027 
00028 
00029 #include <windows.h>
00030 #include <windowsx.h>
00031 #include <Iphlpapi.h>
00032 #include <IPIfCons.h>
00033 
00034 #include <ntddndis.h>
00035 
00036 
00038 char PacketLibraryVersion[64]; 
00040 char PacketDriverVersion[64]; 
00041 
00043 TCHAR   szWindowTitle[] = TEXT("PACKET.DLL");
00044 
00045 //service handles
00046 SC_HANDLE scmHandle = NULL;
00047 SC_HANDLE srvHandle = NULL;
00048 LPCTSTR NPFServiceName = TEXT("NPF");
00049 LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter");
00050 LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\CurrentControlSet\\Services\\NPF");
00051 LPCTSTR NPFDriverPath = TEXT("system32\\drivers\\npf.sys");
00052 
00053 extern PADAPTER_INFO AdaptersInfoList;
00054 extern HANDLE AdaptersInfoMutex;
00055 #ifndef _WINNT4
00056 typedef VOID (*GAAHandler)(
00057   ULONG,
00058   DWORD,
00059   PVOID,
00060   PIP_ADAPTER_ADDRESSES,
00061   PULONG);
00062 GAAHandler GetAdaptersAddressesPointer = NULL;
00063 #endif // _WINNT4
00064 
00065 #ifdef HAVE_DAG_API
00066 /* We load dinamically the dag library in order link it only when it's present on the system */
00067 dagc_open_handler p_dagc_open = NULL;
00068 dagc_close_handler p_dagc_close = NULL;
00069 dagc_getlinktype_handler p_dagc_getlinktype = NULL;
00070 dagc_getlinkspeed_handler p_dagc_getlinkspeed = NULL;
00071 dagc_getfcslen_handler p_dagc_getfcslen = NULL;
00072 dagc_receive_handler p_dagc_receive = NULL;
00073 dagc_wait_handler p_dagc_wait = NULL;
00074 dagc_stats_handler p_dagc_stats = NULL;
00075 dagc_setsnaplen_handler p_dagc_setsnaplen = NULL;
00076 dagc_finddevs_handler p_dagc_finddevs = NULL;
00077 dagc_freedevs_handler p_dagc_freedevs = NULL;
00078 #endif /* HAVE_DAG_API */
00079 
00080 BOOLEAN PacketAddAdapterDag(PCHAR name, PCHAR description, BOOLEAN IsAFile);
00081 
00082 //---------------------------------------------------------------------------
00083 
00088 BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved)
00089 {
00090     BOOLEAN Status=TRUE;
00091     HMODULE IPHMod;
00092 #ifdef HAVE_DAG_API
00093     HMODULE DagcLib;
00094 #endif // HAVE_DAG_API
00095 
00096     switch(Reason)
00097     {
00098     case DLL_PROCESS_ATTACH:
00099 
00100         ODS("************Packet32: DllMain************\n");
00101         
00102 #ifdef _DEBUG_TO_FILE
00103         // dump a bunch of registry keys useful for debug to file
00104         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
00105             "adapters.reg");
00106         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip",
00107             "tcpip.reg");
00108         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\NPF",
00109             "npf.reg");
00110         PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services",
00111             "services.reg");
00112 #endif
00113 
00114         // Create the mutex that will protect the adapter information list
00115         AdaptersInfoMutex = CreateMutex(NULL, FALSE, NULL);
00116 
00117         //
00118         // Retrieve packet.dll version information from the file
00119         //
00120         PacketGetFileVersion(TEXT("packet.dll"), PacketLibraryVersion, sizeof(PacketLibraryVersion));
00121 
00122         //
00123         // Retrieve NPF.sys version information from the file
00124         //
00125         PacketGetFileVersion(TEXT("drivers\\npf.sys"), PacketDriverVersion, sizeof(PacketDriverVersion));
00126 
00127         //
00128         // Locate GetAdaptersAddresses dinamically since it is not present in Win2k
00129         //
00130         IPHMod = GetModuleHandle(TEXT("Iphlpapi"));
00131         
00132 #ifndef _WINNT4
00133         GetAdaptersAddressesPointer = (GAAHandler) GetProcAddress(IPHMod ,"GetAdaptersAddresses");
00134 #endif // _WINNT4
00135 
00136 #ifdef HAVE_DAG_API
00137         /* We load dinamically the dag library in order link it only when it's present on the system */
00138         if((DagcLib =  LoadLibrary(TEXT("dagc.dll"))) == NULL)
00139         {
00140             // Report the error but go on
00141             ODS("dag capture library not found on this system\n");
00142             break;
00143         }
00144 
00145         p_dagc_open = (dagc_open_handler) GetProcAddress(DagcLib, "dagc_open");
00146         p_dagc_close = (dagc_close_handler) GetProcAddress(DagcLib, "dagc_close");
00147         p_dagc_setsnaplen = (dagc_setsnaplen_handler) GetProcAddress(DagcLib, "dagc_setsnaplen");
00148         p_dagc_getlinktype = (dagc_getlinktype_handler) GetProcAddress(DagcLib, "dagc_getlinktype");
00149         p_dagc_getlinkspeed = (dagc_getlinkspeed_handler) GetProcAddress(DagcLib, "dagc_getlinkspeed");
00150         p_dagc_getfcslen = (dagc_getfcslen_handler) GetProcAddress(DagcLib, "dagc_getfcslen");
00151         p_dagc_receive = (dagc_receive_handler) GetProcAddress(DagcLib, "dagc_receive");
00152         p_dagc_wait = (dagc_wait_handler) GetProcAddress(DagcLib, "dagc_wait");
00153         p_dagc_stats = (dagc_stats_handler) GetProcAddress(DagcLib, "dagc_stats");
00154         p_dagc_finddevs = (dagc_finddevs_handler) GetProcAddress(DagcLib, "dagc_finddevs");
00155         p_dagc_freedevs = (dagc_freedevs_handler) GetProcAddress(DagcLib, "dagc_freedevs");
00156         
00157 #endif /* HAVE_DAG_API */
00158 
00159         break;
00160 
00161         case DLL_PROCESS_DETACH:
00162 
00163             CloseHandle(AdaptersInfoMutex);
00164 
00165             break;
00166 
00167         default:
00168             break;
00169     }
00170 
00171     return Status;
00172 }
00173 
00182 ULONG inet_addrU(const WCHAR *cp)
00183 {
00184     ULONG val, part;
00185     WCHAR c;
00186     int i;
00187 
00188     val = 0;
00189     for (i = 0; i < 4; i++) {
00190         part = 0;
00191         while ((c = *cp++) != '\0' && c != '.') {
00192             if (c < '0' || c > '9')
00193                 return -1;
00194             part = part*10 + (c - '0');
00195         }
00196         if (part > 255)
00197             return -1;  
00198         val = val | (part << i*8);
00199         if (i == 3) {
00200             if (c != '\0')
00201                 return -1;  // extra gunk at end of string 
00202         } else {
00203             if (c == '\0')
00204                 return -1;  // string ends early 
00205         }
00206     }
00207     return val;
00208 }
00209 
00216 PWCHAR SChar2WChar(PCHAR string)
00217 {
00218     PWCHAR TmpStr;
00219     TmpStr = (WCHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (strlen(string)+2)*sizeof(WCHAR));
00220 
00221     MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2));
00222 
00223     return TmpStr;
00224 }
00225 
00232 PCHAR WChar2SChar(PWCHAR string)
00233 {
00234     PCHAR TmpStr;
00235     TmpStr = (CHAR*) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, (wcslen(string)+2));
00236 
00237     // Conver to ASCII
00238     WideCharToMultiByte(
00239         CP_ACP,
00240         0,
00241         string,
00242         -1,
00243         TmpStr,
00244         (wcslen(string)+2),          // size of buffer
00245         NULL,
00246         NULL);
00247 
00248     return TmpStr;
00249 }
00250 
00260 BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject)
00261 {
00262     BOOLEAN    Status;
00263     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
00264     PPACKET_OID_DATA  OidData;
00265 
00266     OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
00267     if (OidData == NULL) {
00268         ODS("PacketSetMaxLookaheadsize failed\n");
00269         return FALSE;
00270     }
00271 
00272     //set the size of the lookahead buffer to the maximum available by the the NIC driver
00273     OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD;
00274     OidData->Length=sizeof(ULONG);
00275     Status=PacketRequest(AdapterObject,FALSE,OidData);
00276     OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD;
00277     Status=PacketRequest(AdapterObject,TRUE,OidData);
00278     GlobalFreePtr(OidData);
00279     return Status;
00280 }
00281 
00292 BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject)
00293 {
00294     DWORD BytesReturned;
00295     TCHAR EventName[39];
00296 
00297     // this tells the terminal service to retrieve the event from the global namespace
00298     wcsncpy(EventName,L"Global\\",sizeof(L"Global\\"));
00299 
00300     // retrieve the name of the shared event from the driver
00301     if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE;
00302 
00303     EventName[20]=0; // terminate the string
00304 
00305     // open the shared event
00306     AdapterObject->ReadEvent=CreateEvent(NULL,
00307                                          TRUE,
00308                                          FALSE,
00309                                          EventName);
00310 
00311     // in NT4 "Global\" is not automatically ignored: try to use simply the event name
00312     if(GetLastError()!=ERROR_ALREADY_EXISTS){
00313         if(AdapterObject->ReadEvent != NULL)
00314             CloseHandle(AdapterObject->ReadEvent);
00315         
00316         // open the shared event
00317         AdapterObject->ReadEvent=CreateEvent(NULL,
00318             TRUE,
00319             FALSE,
00320             EventName+7);
00321     }   
00322 
00323     if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){
00324         ODS("PacketSetReadEvt: error retrieving the event from the kernel\n");
00325         return FALSE;
00326     }
00327 
00328     AdapterObject->ReadTimeOut=0;
00329 
00330     return TRUE;
00331 }
00332 
00342 BOOL PacketInstallDriver(SC_HANDLE ascmHandle,SC_HANDLE *srvHandle)
00343 {
00344     BOOL result = FALSE;
00345     ULONG err = 0;
00346     
00347     ODS("installdriver\n");
00348     
00349     *srvHandle = CreateService(ascmHandle, 
00350         NPFServiceName,
00351         NPFServiceDesc,
00352         SERVICE_ALL_ACCESS,
00353         SERVICE_KERNEL_DRIVER,
00354         SERVICE_DEMAND_START,
00355         SERVICE_ERROR_NORMAL,
00356         NPFDriverPath,
00357         NULL, NULL, NULL, NULL, NULL);
00358     if (*srvHandle == NULL) 
00359     {
00360         if (GetLastError() == ERROR_SERVICE_EXISTS) 
00361         {
00362             //npf.sys already existed
00363             result = TRUE;
00364         }
00365     }
00366     else 
00367     {
00368         //Created service for npf.sys
00369         result = TRUE;
00370     }
00371     if (result == TRUE) 
00372         if (*srvHandle != NULL)
00373             CloseServiceHandle(*srvHandle);
00374 
00375     if(result == FALSE){
00376         err = GetLastError();
00377         if(err != 2)
00378             ODSEx("PacketInstallDriver failed, Error=%d\n",err);
00379     }
00380 
00381     SetLastError(err);
00382     return result;
00383     
00384 }
00385 
00395 #ifdef _DEBUG_TO_FILE
00396 
00397 LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName)
00398 {
00399     CHAR Command[256];
00400 
00401     strcpy(Command, "regedit /e ");
00402     strcat(Command, FileName);
00403     strcat(Command, " ");
00404     strcat(Command, KeyName);
00405 
00407     system(Command);
00408 
00409     return TRUE;
00410 }
00411 #endif
00412 
00422 BOOL PacketGetFileVersion(LPTSTR FileName, PCHAR VersionBuff, UINT VersionBuffLen)
00423 {
00424     DWORD   dwVerInfoSize;  // Size of version information block
00425     DWORD   dwVerHnd=0;   // An 'ignored' parameter, always '0'
00426     LPSTR   lpstrVffInfo;
00427     UINT    cbTranslate, dwBytes;
00428     TCHAR   SubBlock[64];
00429     PVOID   lpBuffer;
00430     PCHAR   TmpStr;
00431     
00432     // Structure used to store enumerated languages and code pages.
00433     struct LANGANDCODEPAGE {
00434       WORD wLanguage;
00435       WORD wCodePage;
00436     } *lpTranslate;
00437 
00438     ODS("PacketGetFileVersion\n");
00439 
00440     // Now lets dive in and pull out the version information:
00441     dwVerInfoSize = GetFileVersionInfoSize(FileName, &dwVerHnd);
00442     if (dwVerInfoSize) 
00443     {
00444         lpstrVffInfo = GlobalAllocPtr(GMEM_MOVEABLE, dwVerInfoSize);
00445         if (lpstrVffInfo == NULL)
00446         {
00447             ODS("PacketGetFileVersion: failed to allocate memory\n");
00448             return FALSE;
00449         }
00450 
00451         if(!GetFileVersionInfo(FileName, dwVerHnd, dwVerInfoSize, lpstrVffInfo)) 
00452         {
00453             ODS("PacketGetFileVersion: failed to call GetFileVersionInfo\n");
00454             GlobalFreePtr(lpstrVffInfo);
00455             return FALSE;
00456         }
00457 
00458         // Read the list of languages and code pages.
00459         if(!VerQueryValue(lpstrVffInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate))
00460         {
00461             ODS("PacketGetFileVersion: failed to call VerQueryValue\n");
00462             GlobalFreePtr(lpstrVffInfo);
00463             return FALSE;
00464         }
00465         
00466         // Create the file version string for the first (i.e. the only one) language.
00467         wsprintf( SubBlock, 
00468             TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
00469             (*lpTranslate).wLanguage,
00470             (*lpTranslate).wCodePage);
00471         
00472         // Retrieve the file version string for the language.
00473         if(!VerQueryValue(lpstrVffInfo, SubBlock, &lpBuffer, &dwBytes))
00474         {
00475             ODS("PacketGetFileVersion: failed to call VerQueryValue\n");
00476             GlobalFreePtr(lpstrVffInfo);
00477             return FALSE;
00478         }
00479 
00480         // Convert to ASCII
00481         TmpStr = WChar2SChar(lpBuffer);
00482 
00483         if(strlen(TmpStr) >= VersionBuffLen)
00484         {
00485             ODS("PacketGetFileVersion: Input buffer too small\n");
00486             GlobalFreePtr(lpstrVffInfo);
00487             GlobalFreePtr(TmpStr);
00488             return FALSE;
00489         }
00490 
00491         strcpy(VersionBuff, TmpStr);
00492 
00493         GlobalFreePtr(TmpStr);
00494         
00495       } 
00496     else 
00497     {
00498         ODSEx("PacketGetFileVersion: failed to call GetFileVersionInfoSize, LastError = %d\n", GetLastError());
00499         return FALSE;
00500     
00501     } 
00502     
00503     return TRUE;
00504 }
00505 
00514 LPADAPTER PacketOpenAdapterNPF(PCHAR AdapterName)
00515 {
00516     LPADAPTER lpAdapter;
00517     BOOLEAN Result;
00518     DWORD error;
00519     SC_HANDLE svcHandle = NULL;
00520     LONG KeyRes;
00521     HKEY PathKey;
00522     SERVICE_STATUS SStat;
00523     BOOLEAN QuerySStat;
00524     WCHAR SymbolicLink[128];
00525 
00526     ODS("PacketOpenAdapterNPF\n");
00527     
00528     scmHandle = OpenSCManager(NULL, NULL, GENERIC_READ);
00529     
00530     if(scmHandle == NULL){
00531         error = GetLastError();
00532         ODSEx("OpenSCManager failed! LastError=%d\n", error);
00533     }
00534     else{
00535         // check if the NPF registry key is already present
00536         // this means that the driver is already installed and that we don't need to call PacketInstallDriver
00537         KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
00538             NPFRegistryLocation,
00539             0,
00540             KEY_READ,
00541             &PathKey);
00542         
00543         if(KeyRes != ERROR_SUCCESS)
00544         {
00545             Result = PacketInstallDriver(scmHandle,&svcHandle);
00546         }
00547         else
00548         {
00549             Result = TRUE;
00550             RegCloseKey(PathKey);
00551         }
00552         
00553         if (Result) 
00554         {
00555             
00556             srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS );
00557             if (srvHandle != NULL)
00558             {
00559                 QuerySStat = QueryServiceStatus(srvHandle, &SStat);
00560                 
00561 #if defined(_DBG) || defined(_DEBUG_TO_FILE)                
00562                 switch (SStat.dwCurrentState)
00563                 {
00564                 case SERVICE_CONTINUE_PENDING:
00565                     ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n");
00566                     break;
00567                 case SERVICE_PAUSE_PENDING:
00568                     ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n");
00569                     break;
00570                 case SERVICE_PAUSED:
00571                     ODS("The status of the driver is: SERVICE_PAUSED\n");
00572                     break;
00573                 case SERVICE_RUNNING:
00574                     ODS("The status of the driver is: SERVICE_RUNNING\n");
00575                     break;
00576                 case SERVICE_START_PENDING:
00577                     ODS("The status of the driver is: SERVICE_START_PENDING\n");
00578                     break;
00579                 case SERVICE_STOP_PENDING:
00580                     ODS("The status of the driver is: SERVICE_STOP_PENDING\n");
00581                     break;
00582                 case SERVICE_STOPPED:
00583                     ODS("The status of the driver is: SERVICE_STOPPED\n");
00584                     break;
00585 
00586                 default:
00587                     ODS("The status of the driver is: unknown\n");
00588                     break;
00589                 }
00590 #endif
00591 
00592                 if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING)
00593                 {
00594                     ODS("Calling startservice\n");
00595                     if (StartService(srvHandle, 0, NULL)==0)
00596                     { 
00597                         error = GetLastError();
00598                         if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS)
00599                         {
00600                             SetLastError(error);
00601                             if (scmHandle != NULL) 
00602                                 CloseServiceHandle(scmHandle);
00603                             error = GetLastError();
00604                             ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error);
00605                             SetLastError(error);
00606                             return NULL;
00607                         }
00608                     }               
00609                 }
00610 
00611                 CloseServiceHandle( srvHandle );
00612                 srvHandle = NULL;
00613 
00614             }
00615             else
00616             {
00617                 error = GetLastError();
00618                 ODSEx("OpenService failed! Error=%d", error);
00619                 SetLastError(error);
00620             }
00621         }
00622         else
00623         {
00624             if(KeyRes != ERROR_SUCCESS)
00625                 Result = PacketInstallDriver(scmHandle,&svcHandle);
00626             else
00627                 Result = TRUE;
00628             
00629             if (Result) {
00630                 
00631                 srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START);
00632                 if (srvHandle != NULL)
00633                 {
00634                     
00635                     QuerySStat = QueryServiceStatus(srvHandle, &SStat);
00636 
00637 #if defined(_DBG) || defined(_DEBUG_TO_FILE)                
00638                     switch (SStat.dwCurrentState)
00639                     {
00640                     case SERVICE_CONTINUE_PENDING:
00641                         ODS("The status of the driver is: SERVICE_CONTINUE_PENDING\n");
00642                         break;
00643                     case SERVICE_PAUSE_PENDING:
00644                         ODS("The status of the driver is: SERVICE_PAUSE_PENDING\n");
00645                         break;
00646                     case SERVICE_PAUSED:
00647                         ODS("The status of the driver is: SERVICE_PAUSED\n");
00648                         break;
00649                     case SERVICE_RUNNING:
00650                         ODS("The status of the driver is: SERVICE_RUNNING\n");
00651                         break;
00652                     case SERVICE_START_PENDING:
00653                         ODS("The status of the driver is: SERVICE_START_PENDING\n");
00654                         break;
00655                     case SERVICE_STOP_PENDING:
00656                         ODS("The status of the driver is: SERVICE_STOP_PENDING\n");
00657                         break;
00658                     case SERVICE_STOPPED:
00659                         ODS("The status of the driver is: SERVICE_STOPPED\n");
00660                         break;
00661 
00662                     default:
00663                         ODS("The status of the driver is: unknown\n");
00664                         break;
00665                     }
00666 #endif
00667                     
00668                     if(!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){
00669                         
00670                         ODS("Calling startservice\n");
00671                         
00672                         if (StartService(srvHandle, 0, NULL)==0){ 
00673                             error = GetLastError();
00674                             if(error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){
00675                                 if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00676                                 ODSEx("PacketOpenAdapterNPF: StartService failed, LastError=%d\n",error);
00677                                 SetLastError(error);
00678                                 return NULL;
00679                             }
00680                         }
00681                     }
00682                     
00683                     CloseServiceHandle( srvHandle );
00684                     srvHandle = NULL;
00685 
00686                 }
00687                 else{
00688                     error = GetLastError();
00689                     ODSEx("OpenService failed! LastError=%d", error);
00690                     SetLastError(error);
00691                 }
00692             }
00693         }
00694     }
00695 
00696     if (scmHandle != NULL) CloseServiceHandle(scmHandle);
00697 
00698     lpAdapter=(LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER));
00699     if (lpAdapter==NULL)
00700     {
00701         ODS("PacketOpenAdapterNPF: GlobalAlloc Failed\n");
00702         error=GetLastError();
00703         //set the error to the one on which we failed
00704         SetLastError(error);
00705         ODS("PacketOpenAdapterNPF: Failed to allocate the adapter structure\n");
00706         return NULL;
00707     }
00708     lpAdapter->NumWrites=1;
00709 
00710     wsprintf(SymbolicLink, TEXT("\\\\.\\%s"), &AdapterName[16]);
00711     
00712     // Copy  only the bytes that fit in the adapter structure.
00713     // Note that lpAdapter->SymbolicLink is present for backward compatibility but will
00714     // never be used by the apps
00715     memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH);
00716 
00717     //try if it is possible to open the adapter immediately
00718     lpAdapter->hFile=CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,
00719         0,NULL,OPEN_EXISTING,0,0);
00720     
00721     if (lpAdapter->hFile != INVALID_HANDLE_VALUE) 
00722     {
00723 
00724         if(PacketSetReadEvt(lpAdapter)==FALSE){
00725             error=GetLastError();
00726             ODS("PacketOpenAdapterNPF: Unable to open the read event\n");
00727             GlobalFreePtr(lpAdapter);
00728             //set the error to the one on which we failed
00729             SetLastError(error);
00730             ODSEx("PacketOpenAdapterNPF: PacketSetReadEvt failed, LastError=%d\n",error);
00731             return NULL;
00732         }       
00733         
00734         PacketSetMaxLookaheadsize(lpAdapter);
00735 
00736         _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%S", AdapterName);
00737 
00738         return lpAdapter;
00739     }
00740 
00741 
00742     error=GetLastError();
00743     GlobalFreePtr(lpAdapter);
00744     //set the error to the one on which we failed
00745     ODSEx("PacketOpenAdapterNPF: CreateFile failed, LastError= %d\n",error);
00746     SetLastError(error);
00747     return NULL;
00748 }
00749 
00758 #ifdef HAVE_DAG_API
00759 LPADAPTER PacketOpenAdapterDAG(PCHAR AdapterName, BOOLEAN IsAFile)
00760 {
00761     CHAR DagEbuf[DAGC_ERRBUF_SIZE];
00762     LPADAPTER lpAdapter;
00763     LONG    status;
00764     HKEY dagkey;
00765     DWORD lptype;
00766     DWORD fpc;
00767     DWORD lpcbdata = sizeof(fpc);
00768     WCHAR keyname[512];
00769     PWCHAR tsn;
00770 
00771     
00772     lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
00773         sizeof(ADAPTER));
00774     if (lpAdapter == NULL)
00775     {
00776         return NULL;
00777     }
00778 
00779     if(IsAFile)
00780     {
00781         // We must add an entry to the adapter description list, otherwise many function will not
00782         // be able to work
00783         if(!PacketAddAdapterDag(AdapterName, "DAG file", IsAFile))
00784         {
00785             GlobalFreePtr(lpAdapter);
00786             return NULL;                    
00787         }
00788 
00789         // Flag that this is a DAG file
00790         lpAdapter->Flags = INFO_FLAG_DAG_FILE;
00791     }
00792     else
00793     {
00794         // Flag that this is a DAG card
00795         lpAdapter->Flags = INFO_FLAG_DAG_CARD;
00796     }
00797 
00798     //
00799     // See if the user is asking for fast capture with this device
00800     //
00801 
00802     lpAdapter->DagFastProcess = FALSE;
00803 
00804     tsn = (strstr(strlwr((char*)AdapterName), "dag") != NULL)?
00805         SChar2WChar(strstr(strlwr((char*)AdapterName), "dag")):
00806         L"";
00807 
00808     _snwprintf(keyname, sizeof(keyname), L"%s\\CardParams\\%ws", 
00809         L"SYSTEM\\CurrentControlSet\\Services\\DAG",
00810         tsn);
00811 
00812     GlobalFreePtr(tsn);
00813 
00814     do
00815     {
00816         status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0 , KEY_READ, &dagkey);
00817         if(status != ERROR_SUCCESS)
00818             break;
00819         
00820         status = RegQueryValueEx(dagkey,
00821             L"FastCap",
00822             NULL,
00823             &lptype,
00824             (char*)&fpc,
00825             &lpcbdata);
00826         
00827         if(status == ERROR_SUCCESS)
00828             lpAdapter->DagFastProcess = fpc;
00829         
00830         RegCloseKey(dagkey);
00831     }
00832     while(FALSE);
00833           
00834     //
00835     // Open the card
00836     //
00837     lpAdapter->pDagCard = p_dagc_open(AdapterName,
00838      0, 
00839      DagEbuf);
00840     
00841     if(lpAdapter->pDagCard == NULL)
00842     {
00843         GlobalFreePtr(lpAdapter);
00844         return NULL;                    
00845     }
00846           
00847     lpAdapter->DagFcsLen = p_dagc_getfcslen(lpAdapter->pDagCard);
00848                 
00849     _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterName);
00850     
00851     // XXX we could create the read event here
00852 
00853     return lpAdapter;
00854 }
00855 #endif // HAVE_DAG_API
00856 
00857 //---------------------------------------------------------------------------
00858 // PUBLIC API
00859 //---------------------------------------------------------------------------
00860 
00873 PCHAR PacketGetVersion()
00874 {
00875     return PacketLibraryVersion;
00876 }
00877 
00882 PCHAR PacketGetDriverVersion()
00883 {
00884     return PacketDriverVersion;
00885 }
00886 
00895 BOOL PacketStopDriver()
00896 {
00897     SC_HANDLE       scmHandle;
00898     SC_HANDLE       schService;
00899     BOOL            ret;
00900     SERVICE_STATUS  serviceStatus;
00901 
00902     scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00903     
00904     if(scmHandle != NULL){
00905         
00906         schService = OpenService (scmHandle,
00907             NPFServiceName,
00908             SERVICE_ALL_ACCESS
00909             );
00910         
00911         if (schService != NULL)
00912         {
00913             
00914             ret = ControlService (schService,
00915                 SERVICE_CONTROL_STOP,
00916                 &serviceStatus
00917                 );
00918             if (!ret)
00919             {
00920             }
00921             
00922             CloseServiceHandle (schService);
00923             
00924             CloseServiceHandle(scmHandle);
00925             
00926             return ret;
00927         }
00928     }
00929     
00930     return FALSE;
00931 
00932 }
00933 
00941 LPADAPTER PacketOpenAdapter(PCHAR AdapterName)
00942 {
00943     LPADAPTER lpAdapter;
00944     WCHAR *AdapterNameU;
00945     SC_HANDLE svcHandle = NULL;
00946     PCHAR AdapterNameA = NULL;
00947 #ifndef _WINNT4
00948     PADAPTER_INFO TAdInfo;
00949 #endif // _WINNT4
00950 
00951     ODSEx("PacketOpenAdapter: trying to open the adapter=%s\n",AdapterName)
00952 
00953     if(AdapterName[1]!=0){ //ASCII
00954         
00955         AdapterNameU = SChar2WChar(AdapterName);
00956         AdapterNameA = AdapterName;
00957         AdapterName = (PCHAR)AdapterNameU;
00958     } else {            //Unicode
00959         AdapterNameU = NULL;
00960         AdapterNameA = WChar2SChar((PWCHAR)AdapterName);
00961     }
00962 
00963 #ifndef _WINNT4
00964 
00965     WaitForSingleObject(AdaptersInfoMutex, INFINITE);
00966     // Find the PADAPTER_INFO structure associated with this adapter 
00967     TAdInfo = PacketFindAdInfo(AdapterNameA);
00968     if(TAdInfo == NULL)
00969     {
00970         PacketUpdateAdInfo(AdapterNameA);
00971         TAdInfo = PacketFindAdInfo(AdapterNameA);
00972         if(TAdInfo == NULL)
00973         {
00974 
00975             //can be an ERF file?
00976             lpAdapter = PacketOpenAdapterDAG(AdapterNameA, TRUE);
00977 
00978             if (AdapterNameU != NULL) 
00979                 GlobalFreePtr(AdapterNameU);
00980             else 
00981                 GlobalFreePtr(AdapterNameA);
00982             
00983             ReleaseMutex(AdaptersInfoMutex);
00984             if (lpAdapter == NULL)
00985                 SetLastError(ERROR_BAD_UNIT); //this is the best we can do....
00986             return lpAdapter;
00987         }
00988     }
00989     
00990     if(TAdInfo->Flags != INFO_FLAG_NDIS_ADAPTER)
00991     {
00992         //
00993         // Not a standard NDIS adapter, we must have specific handling
00994         //
00995         
00996 
00997         if(TAdInfo->Flags & INFO_FLAG_NDISWAN_ADAPTER)
00998         {
00999             //
01000             // This is a wan adapter. Open it using the netmon API
01001             //
01002             
01003             lpAdapter = (LPADAPTER) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
01004                 sizeof(ADAPTER));
01005             if (lpAdapter == NULL)
01006             {
01007                 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
01008                 else GlobalFreePtr(AdapterNameA);
01009                 ReleaseMutex(AdaptersInfoMutex);
01010                 SetLastError(ERROR_BAD_UNIT);
01011                 return NULL;
01012             }
01013         
01014             // Backup flags for future usage
01015             lpAdapter->Flags = TAdInfo->Flags;
01016             
01017             // Open the adapter
01018             lpAdapter->pWanAdapter = WanPacketOpenAdapter();
01019             if (lpAdapter->pWanAdapter == NULL)
01020             {
01021                 if (AdapterNameU != NULL) GlobalFreePtr(AdapterNameU);
01022                 else GlobalFreePtr(AdapterNameA);
01023                 
01024                 GlobalFreePtr(lpAdapter);
01025                 ReleaseMutex(AdaptersInfoMutex);
01026                 SetLastError(ERROR_BAD_UNIT);
01027                 return NULL;
01028             }
01029             
01030             _snprintf(lpAdapter->Name, ADAPTER_NAME_LENGTH, "%s", AdapterNameA);
01031             
01032             lpAdapter->ReadEvent = WanPacketGetReadEvent(lpAdapter->pWanAdapter);
01033             
01034             if (AdapterNameU != NULL) 
01035                 GlobalFreePtr(AdapterNameU);
01036             else 
01037                 GlobalFreePtr(AdapterNameA);
01038             
01039             ReleaseMutex(AdaptersInfoMutex);
01040             return lpAdapter;
01041         }
01042         else
01043             if(TAdInfo->Flags & INFO_FLAG_DAG_CARD)
01044             {
01045                 //
01046                 // This is a Dag card. Open it using the dagc API
01047                 //
01048                                 
01049                 lpAdapter = PacketOpenAdapterDAG(AdapterNameA, FALSE);
01050 
01051                 if (AdapterNameU != NULL) 
01052                     GlobalFreePtr(AdapterNameU);
01053                 else 
01054                     GlobalFreePtr(AdapterNameA);
01055 
01056                 ReleaseMutex(AdaptersInfoMutex);
01057                 if (lpAdapter == NULL)
01058                     SetLastError(ERROR_BAD_UNIT);
01059                 return lpAdapter;
01060             }
01061             
01062     }
01063     
01064     ReleaseMutex(AdaptersInfoMutex);
01065 
01066 #endif // _WINNT4
01067    
01068     lpAdapter = PacketOpenAdapterNPF(AdapterName);
01069 
01070     if (AdapterNameU != NULL) 
01071         GlobalFreePtr(AdapterNameU);
01072     else 
01073         GlobalFreePtr(AdapterNameA);
01074 
01075     return lpAdapter;
01076 }
01077 
01084 VOID PacketCloseAdapter(LPADAPTER lpAdapter)
01085 {
01086 
01087 #ifndef _WINNT4
01088     if (lpAdapter->pWanAdapter != NULL)
01089     {
01090         WanPacketCloseAdapter(lpAdapter->pWanAdapter);
01091         GlobalFreePtr(lpAdapter);
01092         return;
01093     }
01094 #ifdef HAVE_DAG_API
01095     else
01096         if(lpAdapter->pDagCard != NULL)
01097         {
01098             if(lpAdapter->Flags & INFO_FLAG_DAG_FILE & ~INFO_FLAG_DAG_CARD)
01099             {
01100                 // This is a file. We must remove the entry in the adapter description list
01101                 PacketUpdateAdInfo(lpAdapter->Name);
01102             }
01103             p_dagc_close(lpAdapter->pDagCard);
01104         }
01105 #endif // HAVE_DAG_API
01106 #endif // _WINNT4
01107     
01108     CloseHandle(lpAdapter->hFile);
01109     SetEvent(lpAdapter->ReadEvent);
01110     CloseHandle(lpAdapter->ReadEvent);
01111     GlobalFreePtr(lpAdapter);
01112 }
01113 
01126 LPPACKET PacketAllocatePacket(void)
01127 {
01128 
01129     LPPACKET    lpPacket;
01130     lpPacket=(LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET));
01131     if (lpPacket==NULL)
01132     {
01133         ODS("PacketAllocatePacket: GlobalAlloc Failed\n");
01134         return NULL;
01135     }
01136     return lpPacket;
01137 }
01138 
01147 VOID PacketFreePacket(LPPACKET lpPacket)
01148 
01149 {
01150     GlobalFreePtr(lpPacket);
01151 }
01152 
01169 VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length)
01170 
01171 {
01172     lpPacket->Buffer = Buffer;
01173     lpPacket->Length = Length;
01174     lpPacket->ulBytesReceived = 0;
01175     lpPacket->bIoComplete = FALSE;
01176 }
01177 
01208 BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
01209 {
01210     BOOLEAN res;
01211     
01212 #ifndef _WINNT4
01213     
01214     if (AdapterObject->pWanAdapter != NULL)
01215     {
01216         lpPacket->ulBytesReceived = WanPacketReceivePacket(AdapterObject->pWanAdapter, lpPacket->Buffer, lpPacket->Length);
01217         return TRUE;
01218     }
01219 #ifdef HAVE_DAG_API
01220     else
01221         if(AdapterObject->pDagCard != NULL)
01222         {
01223 
01224             p_dagc_wait(AdapterObject->pDagCard, &AdapterObject->DagReadTimeout);
01225 
01226             if(p_dagc_receive(AdapterObject->pDagCard, &AdapterObject->DagBuffer, &lpPacket->ulBytesReceived) == 0)
01227                 return TRUE;
01228             else
01229                 return FALSE;
01230         }
01231 #endif // HAVE_DAG_API
01232 #endif // _WINNT4
01233     
01234     if((int)AdapterObject->ReadTimeOut != -1)
01235         WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut);
01236     
01237     res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL);
01238     
01239     return res;
01240 }
01241 
01271 BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync)
01272 {
01273     DWORD        BytesTransfered;
01274     
01275 
01276 #ifndef _WINNT4
01277     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
01278     {
01279         ODS("PacketSendPacket: packet sending not allowed on wan adapters\n");
01280         return FALSE;
01281     }
01282 #endif // _WINNT4
01283 
01284     return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL);
01285 }
01286 
01287 
01315 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync)
01316 {
01317     BOOLEAN         Res;
01318     DWORD           BytesTransfered, TotBytesTransfered=0;
01319     struct timeval  BufStartTime;
01320     LARGE_INTEGER   StartTicks, CurTicks, TargetTicks, TimeFreq;
01321 
01322 
01323     ODS("PacketSendPackets");
01324 
01325 #ifndef _WINNT4
01326     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
01327     {
01328         ODS("PacketSendPackets: packet sending not allowed on wan adapters\n");
01329         return FALSE;
01330     }
01331 #endif // _WINNT4
01332 
01333     // Obtain starting timestamp of the buffer
01334     BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec;
01335     BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
01336 
01337     // Retrieve the reference time counters
01338     QueryPerformanceCounter(&StartTicks);
01339     QueryPerformanceFrequency(&TimeFreq);
01340 
01341     CurTicks.QuadPart = StartTicks.QuadPart;
01342 
01343     do{
01344         // Send the data to the driver
01345         Res = DeviceIoControl(AdapterObject->hFile,
01346             (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC,
01347             (PCHAR)PacketBuff + TotBytesTransfered,
01348             Size - TotBytesTransfered,
01349             NULL,
01350             0,
01351             &BytesTransfered,
01352             NULL);
01353 
01354         TotBytesTransfered += BytesTransfered;
01355 
01356         // calculate the time interval to wait before sending the next packet
01357         TargetTicks.QuadPart = StartTicks.QuadPart +
01358         (LONGLONG)
01359         ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 +
01360         (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *
01361         (TimeFreq.QuadPart) / 1000000;
01362 
01363         // Exit from the loop on termination or error
01364         if(TotBytesTransfered >= Size || Res != TRUE)
01365             break;
01366         
01367         // Wait until the time interval has elapsed
01368         while( CurTicks.QuadPart <= TargetTicks.QuadPart )
01369             QueryPerformanceCounter(&CurTicks);
01370 
01371     }
01372     while(TRUE);
01373 
01374     return TotBytesTransfered;
01375 }
01376 
01395 BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes)
01396 {
01397     DWORD BytesReturned;
01398 
01399 #ifndef _WINNT4
01400    if (AdapterObject->Flags == INFO_FLAG_NDISWAN_ADAPTER)
01401       return WanPacketSetMinToCopy(AdapterObject->pWanAdapter, nbytes);
01402 #ifdef HAVE_DAG_API
01403     else
01404         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
01405             // No mintocopy with DAGs
01406             return TRUE;
01407 #endif // HAVE_DAG_API
01408 #endif // _WINNT4
01409    
01410    return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL);
01411 }
01412 
01449 BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode)
01450 {
01451     DWORD BytesReturned;
01452 
01453 #ifndef _WINNT4
01454    if (AdapterObject->pWanAdapter != NULL)
01455       return WanPacketSetMode(AdapterObject->pWanAdapter, mode);
01456 #endif // _WINNT4
01457 
01458     return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL);
01459 }
01460 
01475 BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len)
01476 {
01477     DWORD       BytesReturned;
01478     WCHAR   *FileName;
01479     BOOLEAN res;
01480     WCHAR   NameWithPath[1024];
01481     int     TStrLen;
01482     WCHAR   *NamePos;
01483 
01484 #ifndef _WINNT4
01485     if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
01486     {
01487         ODS("PacketSetDumpName: not allowed on wan adapters\n");
01488         return FALSE;
01489     }
01490 #endif // _WINNT4
01491 
01492     if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII
01493         FileName=SChar2WChar(name);
01494         len*=2;
01495     } 
01496     else {  //Unicode
01497         FileName=name;
01498     }
01499 
01500     TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos);
01501 
01502     len=TStrLen*2+2;  //add the terminating null character
01503 
01504     // Try to catch malformed strings
01505     if(len>2048){
01506         if(((PUCHAR)name)[1]!=0 && len>1) free(FileName);
01507         return FALSE;
01508     }
01509 
01510     res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL);
01511     free(FileName);
01512     return res;
01513 }
01514 
01530 BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks)
01531 {
01532     DWORD       BytesReturned;
01533     UINT valbuff[2];
01534 
01535 #ifndef _WINNT4
01536     if (AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
01537     {
01538         ODS("PacketSetDumpLimits: not allowed on wan adapters\n");
01539         return FALSE;
01540     }
01541 #endif // _WINNT4
01542 
01543     valbuff[0] = maxfilesize;
01544     valbuff[1] = maxnpacks;
01545 
01546     return DeviceIoControl(AdapterObject->hFile,
01547         pBIOCSETDUMPLIMITS,
01548         valbuff,
01549         sizeof valbuff,
01550         NULL,
01551         0,
01552         &BytesReturned,
01553         NULL);  
01554 }
01555 
01569 BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync)
01570 {
01571     DWORD       BytesReturned;
01572     int     IsDumpEnded;
01573     BOOLEAN res;
01574 
01575 #ifndef _WINNT4
01576     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
01577     {
01578         ODS("PacketIsDumpEnded: not allowed on wan adapters\n");
01579         return FALSE;
01580     }
01581 #endif // _WINNT4
01582 
01583     if(sync)
01584         WaitForSingleObject(AdapterObject->ReadEvent, INFINITE);
01585 
01586     res = DeviceIoControl(AdapterObject->hFile,
01587         pBIOCISDUMPENDED,
01588         NULL,
01589         0,
01590         &IsDumpEnded,
01591         4,
01592         &BytesReturned,
01593         NULL);
01594 
01595     if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished
01596 
01597     return (BOOLEAN)IsDumpEnded;
01598 }
01599 
01619 HANDLE PacketGetReadEvent(LPADAPTER AdapterObject)
01620 {
01621     return AdapterObject->ReadEvent;
01622 }
01623 
01632 BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites)
01633 {
01634     DWORD BytesReturned;
01635 
01636 #ifndef _WINNT4
01637     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
01638     {
01639         ODS("PacketSetNumWrites: not allowed on wan adapters\n");
01640         return FALSE;
01641     }
01642 #endif // _WINNT4
01643 
01644     return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL);
01645 }
01646 
01659 BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout)
01660 {
01661     DWORD BytesReturned;
01662     int DriverTimeOut=-1;
01663 
01664 #ifndef _WINNT4
01665    if (AdapterObject->pWanAdapter != NULL)
01666       return WanPacketSetReadTimeout(AdapterObject->pWanAdapter,timeout);
01667 #endif // _WINNT4
01668 
01669     AdapterObject->ReadTimeOut=timeout;
01670 
01671 #ifdef HAVE_DAG_API
01672     // Under DAG, we simply store the timeout value and then 
01673     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
01674     {
01675         if(timeout == 1)
01676         {
01677             // tell DAG card to return immediately
01678             AdapterObject->DagReadTimeout.tv_sec = 0;
01679             AdapterObject->DagReadTimeout.tv_usec = 0;
01680         }
01681         else
01682             if(timeout == 1)
01683             {
01684                 // tell the DAG card to wait forvever
01685                 AdapterObject->DagReadTimeout.tv_sec = -1;
01686                 AdapterObject->DagReadTimeout.tv_usec = -1;
01687             }
01688             else
01689             {
01690                 // Set the timeout for the DAG card
01691                 AdapterObject->DagReadTimeout.tv_sec = timeout / 1000;
01692                 AdapterObject->DagReadTimeout.tv_usec = (timeout * 1000) % 1000000;
01693             }
01694             
01695             return TRUE;
01696     }
01697 #endif // HAVE_DAG_API
01698 
01699     return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL);
01700 }
01701 
01718 BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim)
01719 {
01720     DWORD BytesReturned;
01721 
01722 #ifndef _WINNT4
01723     if (AdapterObject->pWanAdapter != NULL)
01724         return WanPacketSetBufferSize(AdapterObject->pWanAdapter, dim);
01725 #ifdef HAVE_DAG_API
01726     else
01727         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
01728             // We can't change DAG buffers
01729             return TRUE;
01730 #endif // HAVE_DAG_API
01731 
01732 #endif // _WINNT4
01733     return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL);
01734 }
01735 
01756 BOOLEAN PacketSetBpf(LPADAPTER AdapterObject, struct bpf_program *fp)
01757 {
01758     DWORD BytesReturned;
01759 
01760 #ifndef _WINNT4
01761    if (AdapterObject->pWanAdapter != NULL)
01762       return WanPacketSetBpfFilter(AdapterObject->pWanAdapter, (PUCHAR)fp->bf_insns, fp->bf_len * sizeof(struct bpf_insn));
01763 #ifdef HAVE_DAG_API
01764     else
01765         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
01766             // Delegate the filtering to higher layers since it's too expensive here
01767             return TRUE;
01768 #endif // HAVE_DAG_API
01769 #endif // _WINNT4
01770 
01771    return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL);
01772 }
01773 
01788 INT PacketSetSnapLen(LPADAPTER AdapterObject, int snaplen)
01789 {
01790 
01791 #ifdef HAVE_DAG_API
01792     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
01793         return p_dagc_setsnaplen(AdapterObject->pDagCard, snaplen);
01794     else
01795 #endif // HAVE_DAG_API
01796         return 0;
01797 }
01798 
01812 BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s)
01813 {
01814     BOOLEAN Res;
01815     DWORD BytesReturned;
01816     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
01817     
01818 #ifndef _WINNT4
01819 #ifdef HAVE_DAG_API
01820     if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
01821     {
01822         dagc_stats_t DagStats;
01823         
01824         // Note: DAG cards are currently very limited from the statistics reporting point of view,
01825         // so most of the values returned by dagc_stats() are zero at the moment
01826         if(p_dagc_stats(AdapterObject->pDagCard, &DagStats) == 0)
01827         {
01828             // XXX: Only copy the dropped packets for now, since the received counter is not supported by
01829             // DAGS at the moment
01830 
01831             s->bs_recv = (ULONG)DagStats.received;
01832             s->bs_drop = (ULONG)DagStats.dropped;
01833             return TRUE;
01834         }
01835         else
01836             return FALSE;
01837     }
01838     else
01839 #endif // HAVE_DAG_API
01840         if ( AdapterObject->pWanAdapter != NULL)
01841             Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat);
01842         else
01843 #endif // _WINNT4
01844             
01845             Res = DeviceIoControl(AdapterObject->hFile,
01846             pBIOCGSTATS,
01847             NULL,
01848             0,
01849             &tmpstat,
01850             sizeof(struct bpf_stat),
01851             &BytesReturned,
01852             NULL);
01853         
01854 
01855     // Copy only the first two values retrieved from the driver
01856     s->bs_recv = tmpstat.bs_recv;
01857     s->bs_drop = tmpstat.bs_drop;
01858 
01859     return Res;
01860 }
01861 
01874 BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s)
01875 {
01876     BOOLEAN Res;
01877     DWORD BytesReturned;
01878     struct bpf_stat tmpstat;    // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications
01879 
01880 #ifndef _WINNT4
01881 #ifdef HAVE_DAG_API
01882         if(AdapterObject->Flags & INFO_FLAG_DAG_CARD)
01883         {
01884             dagc_stats_t DagStats;
01885 
01886             // Note: DAG cards are currently very limited from the statistics reporting point of view,
01887             // so most of the values returned by dagc_stats() are zero at the moment
01888             p_dagc_stats(AdapterObject->pDagCard, &DagStats);
01889             s->bs_recv = (ULONG)DagStats.received;
01890             s->bs_drop = (ULONG)DagStats.dropped;
01891             s->ps_ifdrop = 0;
01892             s->bs_capt = (ULONG)DagStats.captured;
01893         }
01894 #endif // HAVE_DAG_API
01895    if(AdapterObject->pWanAdapter != NULL)
01896         Res = WanPacketGetStats(AdapterObject->pWanAdapter, (PVOID)&tmpstat);
01897     else
01898 #endif // _WINNT4
01899 
01900     Res = DeviceIoControl(AdapterObject->hFile,
01901         pBIOCGSTATS,
01902         NULL,
01903         0,
01904         &tmpstat,
01905         sizeof(struct bpf_stat),
01906         &BytesReturned,
01907         NULL);
01908 
01909     s->bs_recv = tmpstat.bs_recv;
01910     s->bs_drop = tmpstat.bs_drop;
01911     s->ps_ifdrop = tmpstat.ps_ifdrop;
01912     s->bs_capt = tmpstat.bs_capt;
01913 
01914     return Res;
01915 }
01916 
01929 BOOLEAN PacketRequest(LPADAPTER  AdapterObject,BOOLEAN Set,PPACKET_OID_DATA  OidData)
01930 {
01931     DWORD       BytesReturned;
01932     BOOLEAN     Result;
01933 
01934 #ifndef _WINNT4
01935     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
01936         return FALSE;
01937 #endif // _WINNT4
01938     
01939     Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? (DWORD)pBIOCSETOID : (DWORD)pBIOCQUERYOID,
01940                            OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData,
01941                            sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);
01942     
01943     // output some debug info
01944     ODSEx("PacketRequest, OID=%d ", OidData->Oid);
01945     ODSEx("Length=%d ", OidData->Length);
01946     ODSEx("Set=%d ", Set);
01947     ODSEx("Res=%d\n", Result);
01948 
01949     return Result;
01950 }
01951 
01968 BOOLEAN PacketSetHwFilter(LPADAPTER  AdapterObject,ULONG Filter)
01969 {
01970     BOOLEAN    Status;
01971     ULONG      IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
01972     PPACKET_OID_DATA  OidData;
01973 
01974 #ifndef _WINNT4
01975     if(AdapterObject->Flags != INFO_FLAG_NDIS_ADAPTER)
01976         return TRUE;
01977 #endif // _WINNT4
01978     
01979     OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
01980     if (OidData == NULL) {
01981         ODS("PacketSetHwFilter: GlobalAlloc Failed\n");
01982         return FALSE;
01983     }
01984     OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER;
01985     OidData->Length=sizeof(ULONG);
01986     *((PULONG)OidData->Data)=Filter;
01987     Status=PacketRequest(AdapterObject,TRUE,OidData);
01988     GlobalFreePtr(OidData);
01989     return Status;
01990 }
01991 
02013 BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG  BufferSize)
02014 {
02015     PADAPTER_INFO   TAdInfo;
02016     ULONG   SizeNeeded = 1;
02017     ULONG   SizeNames = 1;
02018     ULONG   SizeDesc;
02019     ULONG   OffDescriptions;
02020 
02021     ODSEx("PacketGetAdapterNames: BufferSize=%d\n", *BufferSize);
02022 
02023     //
02024     // Create the adapter information list
02025     //
02026     PacketPopulateAdaptersInfoList();
02027 
02028     WaitForSingleObject(AdaptersInfoMutex, INFINITE);
02029     if(!AdaptersInfoList) 
02030     {
02031         ReleaseMutex(AdaptersInfoMutex);
02032         *BufferSize = 0;
02033         return FALSE;       // No adapters to return
02034     }
02035 
02036     // 
02037     // First scan of the list to calculate the offsets and check the sizes
02038     //
02039     for(TAdInfo = AdaptersInfoList; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
02040     {
02041         // Update the size variables
02042         SizeNeeded += strlen(TAdInfo->Name) + strlen(TAdInfo->Description) + 2;
02043         SizeNames += strlen(TAdInfo->Name) + 1;     
02044     }
02045 
02046     // Chack that we don't overflow the buffer.
02047     // Note: 2 is the number of additional separators needed inside the list
02048     if(SizeNeeded + 2 >= *BufferSize || pStr == NULL)
02049     {
02050         ReleaseMutex(AdaptersInfoMutex);
02051 
02052         ODS("PacketGetAdapterNames: input buffer too small\n");
02053         *BufferSize = SizeNeeded + 4;  // Report the required size
02054         return FALSE;
02055     }
02056 
02057 
02058     OffDescriptions = SizeNames;
02059 
02060     // 
02061     // Second scan of the list to copy the information
02062     //
02063     for(TAdInfo = AdaptersInfoList, SizeNames = 0, SizeDesc = 0; TAdInfo != NULL; TAdInfo = TAdInfo->Next)
02064     {
02065         // Copy the data
02066         strcpy(((PCHAR)pStr) + SizeNames, TAdInfo->Name);
02067         strcpy(((PCHAR)pStr) + OffDescriptions + SizeDesc, TAdInfo->Description);
02068 
02069         // Update the size variables
02070         SizeNames += strlen(TAdInfo->Name) + 1;
02071         SizeDesc += strlen(TAdInfo->Description) + 1;
02072     }
02073 
02074     // Separate the two lists
02075     ((PCHAR)pStr)[SizeNames] = 0;
02076 
02077     // End the list with a further \0
02078     ((PCHAR)pStr)[SizeNeeded] = 0;
02079 
02080 
02081     ReleaseMutex(AdaptersInfoMutex);
02082     return TRUE;
02083 }
02084 
02098 BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries)
02099 {
02100     PADAPTER_INFO TAdInfo;
02101     PCHAR Tname;
02102     BOOLEAN Res, FreeBuff;
02103 
02104     ODS("PacketGetNetInfo\n");
02105 
02106     // Provide conversion for backward compatibility
02107     if(AdapterName[1] != 0)
02108     { //ASCII
02109         Tname = AdapterName;
02110         FreeBuff = FALSE;
02111     }
02112     else
02113     {
02114         Tname = WChar2SChar((PWCHAR)AdapterName);
02115         FreeBuff = TRUE;
02116     }
02117 
02118     //
02119     // Update the information about this adapter
02120     //
02121     if(!PacketUpdateAdInfo(Tname))
02122     {
02123         ODS("PacketGetNetInfo: Adapter not found\n");
02124         if(FreeBuff)GlobalFreePtr(Tname);
02125         return FALSE;
02126     }
02127     
02128     WaitForSingleObject(AdaptersInfoMutex, INFINITE);
02129     // Find the PADAPTER_INFO structure associated with this adapter 
02130     TAdInfo = PacketFindAdInfo(Tname);
02131 
02132     if(TAdInfo != NULL)
02133     {
02134         *NEntries = (TAdInfo->NNetworkAddresses < *NEntries)? TAdInfo->NNetworkAddresses: *NEntries;
02135         //TODO what if nentries = 0?
02136         if (*NEntries > 0)
02137             memcpy(buffer, TAdInfo->NetworkAddresses, *NEntries * sizeof(npf_if_addr));
02138         Res = TRUE;
02139     }
02140     else
02141     {
02142         ODS("PacketGetNetInfo: Adapter not found\n");
02143         Res = FALSE;
02144     }
02145     
02146     ReleaseMutex(AdaptersInfoMutex);
02147     
02148     if(FreeBuff)GlobalFreePtr(Tname);
02149     
02150     return Res;
02151 }
02152 
02169 BOOLEAN PacketGetNetType(LPADAPTER AdapterObject, NetType *type)
02170 {
02171     PADAPTER_INFO TAdInfo;
02172     BOOLEAN ret;    
02173     ODS("PacketGetNetType\n");
02174 
02175     WaitForSingleObject(AdaptersInfoMutex, INFINITE);
02176     // Find the PADAPTER_INFO structure associated with this adapter 
02177     TAdInfo = PacketFindAdInfo(AdapterObject->Name);
02178 
02179     if(TAdInfo != NULL)
02180     {
02181         // Copy the data
02182         memcpy(type, &(TAdInfo->LinkLayer), sizeof(struct NetType));
02183         ret = TRUE;
02184     }
02185     else
02186     {
02187         ODS("PacketGetNetType: Adapter not found\n");
02188         ret =  FALSE;
02189     }
02190 
02191     ReleaseMutex(AdaptersInfoMutex);
02192 
02193     return ret;
02194 }
02195 
02196 /* @} */

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