diff --git a/reactos/dll/win32/packet/Packet32.c b/reactos/dll/win32/packet/Packet32.c deleted file mode 100644 index 1e2531cc870..00000000000 --- a/reactos/dll/win32/packet/Packet32.c +++ /dev/null @@ -1,2057 +0,0 @@ -/* - * Copyright (c) 1999, 2000 - * Politecnico di Torino. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the Politecnico - * di Torino, and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define UNICODE 1 - -#include -#include -#include -#include - -#include -#include "trace.h" - - -/****** KERNEL Macro APIs ******************************************************/ - -#define GetInstanceModule(hInst) (HMODULE)(hInst) -#define GlobalPtrHandle(lp) ((HGLOBAL)GlobalHandle(lp)) -#define GlobalLockPtr(lp) ((BOOL)GlobalLock(GlobalPtrHandle(lp))) -#define GlobalUnlockPtr(lp) GlobalUnlock(GlobalPtrHandle(lp)) -#define GlobalAllocPtr(flags, cb) (GlobalLock(GlobalAlloc((flags), (cb)))) -#define GlobalReAllocPtr(lp, cbNew, flags) (GlobalUnlockPtr(lp), GlobalLock(GlobalReAlloc(GlobalPtrHandle(lp) , (cbNew), (flags)))) -#define GlobalFreePtr(lp) (GlobalUnlockPtr(lp), (BOOL)(ULONG_PTR)GlobalFree(GlobalPtrHandle(lp))) - -#undef GMEM_MOVEABLE -#define GMEM_MOVEABLE 0 - - - -/// Title of error windows -TCHAR szWindowTitle[] = TEXT("PACKET.DLL"); - -#if DBG -#define ODS(_x) OutputDebugString(TEXT(_x)) -//#define ODSEx(_x, _y) -#define ODSEx TRACE -#else -#ifdef _DEBUG_TO_FILE -#include -/*! - \brief Macro to print a debug string. The behavior differs depending on the debug level -*/ -#define ODS(_x) { \ - FILE *f; \ - f = fopen("winpcap_debug.txt", "a"); \ - fprintf(f, "%s", _x); \ - fclose(f); \ -} -/*! - \brief Macro to print debug data with the printf convention. The behavior differs depending on - the debug level -*/ -#define ODSEx(_x, _y) { \ - FILE *f; \ - f = fopen("winpcap_debug.txt", "a"); \ - fprintf(f, _x, _y); \ - fclose(f); \ -} - -LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName); -#else -#define ODS(_x) -#define ODSEx(_x, _y) -#endif -#endif - -//service handles -SC_HANDLE scmHandle = NULL; -SC_HANDLE srvHandle = NULL; -LPCTSTR NPFServiceName = TEXT("NPF"); -LPCTSTR NPFServiceDesc = TEXT("Netgroup Packet Filter"); -LPCTSTR NPFDriverName = TEXT("\\npf.sys"); -LPCTSTR NPFRegistryLocation = TEXT("SYSTEM\\ControlSet001\\Services\\NPF"); - - -//--------------------------------------------------------------------------- - -/*! - \brief The main dll function. -*/ - -BOOL APIENTRY DllMain (HANDLE DllHandle,DWORD Reason,LPVOID lpReserved) -{ - BOOLEAN Status=TRUE; - - switch ( Reason ) - { - case DLL_PROCESS_ATTACH: - - ODS("\n************Packet32: DllMain************\n"); - -#ifdef _DEBUG_TO_FILE - // dump a bunch of registry keys useful for debug to file - PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", - "adapters.reg"); - PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Tcpip", - "tcpip.reg"); - PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\NPF", - "npf.reg"); - PacketDumpRegistryKey("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services", - "services.reg"); -#endif - break; - - case DLL_PROCESS_DETACH: - break; - - default: - break; - } - - return Status; -} - -/*! - \brief Converts an ASCII string to UNICODE. Uses the MultiByteToWideChar() system function. - \param string The string to convert. - \return The converted string. -*/ - -WCHAR* SChar2WChar(char* string) -{ - WCHAR* TmpStr; - TmpStr=(WCHAR*) malloc ((strlen(string)+2)*sizeof(WCHAR)); - - MultiByteToWideChar(CP_ACP, 0, string, -1, TmpStr, (strlen(string)+2)); - - return TmpStr; -} - -/*! - \brief Sets the maximum possible lookahead buffer for the driver's Packet_tap() function. - \param AdapterObject Handle to the service control manager. - \return If the function succeeds, the return value is nonzero. - - The lookahead buffer is the portion of packet that Packet_tap() can access from the NIC driver's memory - without performing a copy. This function tries to increase the size of that buffer. -*/ - -BOOLEAN PacketSetMaxLookaheadsize (LPADAPTER AdapterObject) -{ - BOOLEAN Status; - ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); - PPACKET_OID_DATA OidData; - - OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); - if (OidData == NULL) { - ODS("PacketSetMaxLookaheadsize failed\n"); - return FALSE; - } - - //set the size of the lookahead buffer to the maximum available by the the NIC driver - OidData->Oid=OID_GEN_MAXIMUM_LOOKAHEAD; - OidData->Length=sizeof(ULONG); - Status=PacketRequest(AdapterObject,FALSE,OidData); - OidData->Oid=OID_GEN_CURRENT_LOOKAHEAD; - Status=PacketRequest(AdapterObject,TRUE,OidData); - GlobalFreePtr(OidData); - return Status; -} - -/*! - \brief Retrieves the event associated in the driver with a capture instance and stores it in an - _ADAPTER structure. - \param AdapterObject Handle to the service control manager. - \return If the function succeeds, the return value is nonzero. - - This function is used by PacketOpenAdapter() to retrieve the read event from the driver by means of an ioctl - call and set it in the _ADAPTER structure pointed by AdapterObject. -*/ - -BOOLEAN PacketSetReadEvt(LPADAPTER AdapterObject) -{ - DWORD BytesReturned; - WCHAR EventName[39]; - - // this tells the terminal service to retrieve the event from the global namespace - wcsncpy(EventName,L"Global\\",sizeof(L"Global\\")); - - // retrieve the name of the shared event from the driver - if(DeviceIoControl(AdapterObject->hFile,pBIOCEVNAME,NULL,0,EventName+7,13*sizeof(TCHAR),&BytesReturned,NULL)==FALSE) return FALSE; - - EventName[20]=0; // terminate the string - - // open the shared event - AdapterObject->ReadEvent=CreateEventW(NULL, - TRUE, - FALSE, - EventName); - - // in NT4 "Global\" is not automatically ignored: try to use simply the event name - if(GetLastError()!=ERROR_ALREADY_EXISTS){ - if(AdapterObject->ReadEvent != NULL) - CloseHandle(AdapterObject->ReadEvent); - - // open the shared event - AdapterObject->ReadEvent=CreateEventW(NULL, - TRUE, - FALSE, - EventName+7); - } - - if(AdapterObject->ReadEvent==NULL || GetLastError()!=ERROR_ALREADY_EXISTS){ - ODS("PacketSetReadEvt: error retrieving the event from the kernel\n"); - return FALSE; - } - - AdapterObject->ReadTimeOut=0; - - return TRUE; - -} - -/*! - \brief Installs the NPF device driver. - \param ascmHandle Handle to the service control manager. - \param ascmHandle A pointer to a handle that will receive the pointer to the driver's service. - \param driverPath The full path of the .sys file to load. - \return If the function succeeds, the return value is nonzero. - - This function installs the driver's service in the system using the CreateService function. -*/ - -BOOL PacketInstallDriver(SC_HANDLE ascmHandle, SC_HANDLE* srvHandle, TCHAR* driverPath) -{ - BOOL result = FALSE; - ULONG err; - - ODS("installdriver\n"); - - if (GetFileAttributes(driverPath) != 0xffffffff) { - *srvHandle = CreateService(ascmHandle, - NPFServiceName, - NPFServiceDesc, - SERVICE_ALL_ACCESS, - SERVICE_KERNEL_DRIVER, - SERVICE_DEMAND_START, - SERVICE_ERROR_NORMAL, - driverPath, - NULL, NULL, NULL, NULL, NULL); - if (*srvHandle == NULL) { - if (GetLastError() == ERROR_SERVICE_EXISTS) { - //npf.sys already existed - result = TRUE; - } - } else { - //Created service for npf.sys - result = TRUE; - } - } - if (result == TRUE) { - if (*srvHandle != NULL) { - CloseServiceHandle(*srvHandle); - } - } - - if (result == FALSE){ - err = GetLastError(); - if (err != 2) { - ODSEx("PacketInstallDriver failed, Error=%d\n",err); - } - } - return result; - -} - -/*! - \brief Convert a Unicode dotted-quad to a 32-bit IP address. - \param cp A string containing the address. - \return the converted 32-bit numeric address. - - Doesn't check to make sure the address is valid. -*/ - - -ULONG inet_addrU(const WCHAR *cp) -{ - ULONG val, part; - WCHAR c; - int i; - - val = 0; - for (i = 0; i < 4; i++) { - part = 0; - while ((c = *cp++) != '\0' && c != '.') { - if (c < '0' || c > '9') - return -1; - part = part*10 + (c - '0'); - } - if (part > 255) - return -1; - val = val | (part << i*8); - if (i == 3) { - if (c != '\0') - return -1; // extra gunk at end of string - } else { - if (c == '\0') - return -1; // string ends early - } - } - return val; -} - -/*! - \brief Dumps a registry key to disk in text format. Uses regedit. - \param KeyName Name of the ket to dump. All its subkeys will be saved recursively. - \param FileName Name of the file that will contain the dump. - \return If the function succeeds, the return value is nonzero. - - For debugging purposes, we use this function to obtain some registry keys from the user's machine. -*/ - -#ifdef _DEBUG_TO_FILE - -LONG PacketDumpRegistryKey(PCHAR KeyName, PCHAR FileName) -{ - CHAR Command[256]; - - strcpy(Command, "regedit /e "); - strcat(Command, FileName); - strcat(Command, " "); - strcat(Command, KeyName); - - /// Let regedit do the dirt work for us - system(Command); - - return TRUE; -} -#endif - -//--------------------------------------------------------------------------- -// PUBLIC API -//--------------------------------------------------------------------------- - -/** @ingroup packetapi - * @{ - */ - -/** @defgroup packet32 Packet.dll exported functions and variables - * @{ - */ - -/// Current packet.dll Version. It can be retrieved directly or through the PacketGetVersion() function. -char PacketLibraryVersion[] = "2.3"; - -/*! - \brief Returns a string with the dll version. - \return A char pointer to the version of the library. -*/ -PCHAR PacketGetVersion(){ - return PacketLibraryVersion; -} - -/*! - \brief Returns information about the MAC type of an adapter. - \param AdapterObject The adapter on which information is needed. - \param type Pointer to a NetType structure that will be filled by the function. - \return If the function succeeds, the return value is nonzero, otherwise the return value is zero. - - This function return the link layer technology and the speed (in bps) of an opened adapter. - The LinkType field of the type parameter can have one of the following values: - - - NdisMedium802_3: Ethernet (802.3) - - NdisMediumWan: WAN - - NdisMedium802_5: Token Ring (802.5) - - NdisMediumFddi: FDDI - - NdisMediumAtm: ATM - - NdisMediumArcnet878_2: ARCNET (878.2) -*/ -BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type) -{ - BOOLEAN Status; - ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); - PPACKET_OID_DATA OidData; - - OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); - if (OidData == NULL) { - ODS("PacketGetNetType failed\n"); - return FALSE; - } - //get the link-layer type - OidData->Oid = OID_GEN_MEDIA_IN_USE; - OidData->Length = sizeof (ULONG); - Status = PacketRequest(AdapterObject,FALSE,OidData); - type->LinkType=*((UINT*)OidData->Data); - - //get the link-layer speed - OidData->Oid = OID_GEN_LINK_SPEED; - OidData->Length = sizeof (ULONG); - Status = PacketRequest(AdapterObject,FALSE,OidData); - type->LinkSpeed=*((UINT*)OidData->Data)*100; - GlobalFreePtr (OidData); - - ODSEx("Media:%d ",type->LinkType); - ODSEx("Speed=%d\n",type->LinkSpeed); - - return Status; -} - -/*! - \brief Stops and unloads the WinPcap device driver. - \return If the function succeeds, the return value is nonzero, otherwise it is zero. - - This function can be used to unload the driver from memory when the application no more needs it. - Note that the driver is physically stopped and unloaded only when all the files on its devices - are closed, i.e. when all the applications that use WinPcap close all their adapters. -*/ -BOOL PacketStopDriver() -{ - SC_HANDLE scmHandle; - SC_HANDLE schService; - BOOL ret; - SERVICE_STATUS serviceStatus; - - scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - - if(scmHandle != NULL){ - - schService = OpenService (scmHandle, - NPFServiceName, - SERVICE_ALL_ACCESS - ); - - if (schService != NULL) - { - - ret = ControlService (schService, - SERVICE_CONTROL_STOP, - &serviceStatus - ); - if (!ret) - { - } - - CloseServiceHandle (schService); - - CloseServiceHandle(scmHandle); - - return ret; - } - } - - return FALSE; - -} - -/*! - \brief Opens an adapter. - \param AdapterName A string containing the name of the device to open. - Use the PacketGetAdapterNames() function to retrieve the list of available devices. - \return If the function succeeds, the return value is the pointer to a properly initialized ADAPTER object, - otherwise the return value is NULL. - - This function tries to load and start the packet driver at the first invocation. In this way, - the management of the driver is transparent to the application, that simply needs to open an adapter to start - WinPcap. - - \note the Windows 95 version of the NPF driver works with the ASCII string format, while the Windows NT - version works with UNICODE. Therefore, AdapterName \b should be an ASCII string in Windows 95, and a UNICODE - string in Windows NT. This difference is not a problem if the string pointed by AdapterName was obtained - through the PacketGetAdapterNames function, because it returns the names of the adapters in the proper format. - Problems can arise in Windows NT when the string is obtained from ANSI C functions like scanf, because they - use the ASCII format. Since this could be a relevant problem during the porting of command-line applications - from UNIX, we included in the Windows NT version of PacketOpenAdapter the ability to detect ASCII strings and - convert them to UNICODE before sending them to the device driver. Therefore PacketOpenAdapter in Windows NT - accepts both the ASCII and the UNICODE format. If a ASCII string is received, it is converted to UNICODE - by PACKET.DLL before being passed to the driver. -*/ -LPADAPTER PacketOpenAdapter(LPTSTR AdapterName) -{ - LPADAPTER lpAdapter; - BOOLEAN Result; - char *AdapterNameA; - WCHAR *AdapterNameU; - DWORD error; - SC_HANDLE svcHandle = NULL; - TCHAR driverPath[512]; - TCHAR WinPath[256]; - LONG KeyRes; - HKEY PathKey; - SERVICE_STATUS SStat; - BOOLEAN QuerySStat; - WCHAR SymbolicLink[128]; - - ODSEx("PacketOpenAdapter: trying to open the adapter=%S\n",AdapterName); - - scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); - if(scmHandle == NULL){ - error = GetLastError(); - ODSEx("OpenSCManager failed! Error=%d\n", error); - } else { - *driverPath = 0; - GetCurrentDirectory(512, driverPath); - wsprintf(driverPath + wcslen(driverPath), NPFDriverName); - - // check if the NPF registry key is already present - // this means that the driver is already installed and that we don't need to call PacketInstallDriver - KeyRes=RegOpenKeyEx(HKEY_LOCAL_MACHINE, - NPFRegistryLocation, - 0, - KEY_READ, - &PathKey); - - if(KeyRes != ERROR_SUCCESS){ - Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath); - } else { - Result = TRUE; - RegCloseKey(PathKey); - } - - if (Result) { - - srvHandle = OpenService(scmHandle, NPFServiceName, SERVICE_START | SERVICE_QUERY_STATUS ); - if (srvHandle != NULL){ - - QuerySStat = QueryServiceStatus(srvHandle, &SStat); - ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState); - - if (!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING){ - ODS("Calling startservice\n"); - if (StartService(srvHandle, 0, NULL)==0){ - error = GetLastError(); - if (error!=ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS){ - SetLastError(error); - if (scmHandle != NULL) CloseServiceHandle(scmHandle); - error = GetLastError(); - ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error); - return NULL; - } - } - } - } else { - error = GetLastError(); - ODSEx("OpenService failed! Error=%d", error); - } - } else { - if (GetSystemDirectory(WinPath, sizeof(WinPath)/sizeof(TCHAR)) == 0) { - return FALSE; - } - wsprintf(driverPath, TEXT("%s\\drivers%s"), WinPath, NPFDriverName); - - if (KeyRes != ERROR_SUCCESS) { - Result = PacketInstallDriver(scmHandle,&svcHandle,driverPath); - } else { - Result = TRUE; - } - if (Result) { - srvHandle = OpenService(scmHandle,NPFServiceName,SERVICE_START); - if (srvHandle != NULL) { - QuerySStat = QueryServiceStatus(srvHandle, &SStat); - ODSEx("The status of the driver is:%d\n",SStat.dwCurrentState); - if (!QuerySStat || SStat.dwCurrentState != SERVICE_RUNNING) { - ODS("Calling startservice\n"); - if (StartService(srvHandle, 0, NULL) == 0) { - error = GetLastError(); - if (error != ERROR_SERVICE_ALREADY_RUNNING && error!=ERROR_ALREADY_EXISTS) { - SetLastError(error); - if (scmHandle != NULL) CloseServiceHandle(scmHandle); - ODSEx("PacketOpenAdapter: StartService failed, Error=%d\n",error); - return NULL; - } - } - } - } else { - error = GetLastError(); - ODSEx("OpenService failed! Error=%d", error); - } - } - } - } - if (scmHandle != NULL) CloseServiceHandle(scmHandle); - - AdapterNameA = (char*)AdapterName; - if (AdapterNameA[1] != 0) { // ASCII - AdapterNameU = SChar2WChar(AdapterNameA); - AdapterName = AdapterNameU; - } else { // Unicode - AdapterNameU = NULL; - } - - lpAdapter = (LPADAPTER)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(ADAPTER)); - if (lpAdapter == NULL) { - ODS("PacketOpenAdapter: GlobalAlloc Failed\n"); - error = GetLastError(); - if (AdapterNameU != NULL) free(AdapterNameU); - //set the error to the one on which we failed - SetLastError(error); - ODS("PacketOpenAdapter: Failed to allocate the adapter structure\n"); - return NULL; - } - lpAdapter->NumWrites = 1; - - wsprintf(SymbolicLink,TEXT("\\\\.\\%s%s"), DOSNAMEPREFIX, &AdapterName[8]); - - // Copy only the bytes that fit in the adapter structure. - // Note that lpAdapter->SymbolicLink is present for backward compatibility but will - // never be used by the apps - memcpy(lpAdapter->SymbolicLink, (PCHAR)SymbolicLink, MAX_LINK_NAME_LENGTH); - - //try if it is possible to open the adapter immediately - lpAdapter->hFile = CreateFile(SymbolicLink,GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,0,0); - - if (lpAdapter->hFile != INVALID_HANDLE_VALUE) { - ODSEx("PacketOpenAdapter: CreateFile(%S) successfull\n", SymbolicLink); - if (PacketSetReadEvt(lpAdapter) == FALSE) { - error = GetLastError(); - ODS("PacketOpenAdapter: Unable to open the read event\n"); - if (AdapterNameU != NULL) - free(AdapterNameU); - GlobalFreePtr(lpAdapter); - //set the error to the one on which we failed - SetLastError(error); - ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=%d\n",error); - return NULL; - } - - PacketSetMaxLookaheadsize(lpAdapter); - if (AdapterNameU != NULL) - free(AdapterNameU); - return lpAdapter; - } - //this is probably the first request on the packet driver. - //We must create the dos device and set the access rights on it - else { - Result = DefineDosDevice(DDD_RAW_TARGET_PATH, - &SymbolicLink[4], - AdapterName); - if (Result) { - - ODSEx("PacketOpenAdapter: calling CreateFile(%S)\n", SymbolicLink); - - lpAdapter->hFile = CreateFile( - SymbolicLink, - GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,0,0); - if (lpAdapter->hFile != INVALID_HANDLE_VALUE) { - if (PacketSetReadEvt(lpAdapter) == FALSE) { - error = GetLastError(); - ODS("PacketOpenAdapter: Unable to open the read event\n"); - if (AdapterNameU != NULL) - free(AdapterNameU); - GlobalFreePtr(lpAdapter); - //set the error to the one on which we failed - SetLastError(error); - ODSEx("PacketOpenAdapter: PacketSetReadEvt failed, Error=1,%d\n",error); - return NULL; - } - PacketSetMaxLookaheadsize(lpAdapter); - if (AdapterNameU != NULL) - free(AdapterNameU); - return lpAdapter; - } else { - ODS("PacketOpenAdapter: CreateFile failed\n"); - } - } else { - ODSEx("PacketOpenAdapter: DefineDosDevice(%S) failed\n", &SymbolicLink[4]); - } - } - error = GetLastError(); - if (AdapterNameU != NULL) - free(AdapterNameU); - GlobalFreePtr(lpAdapter); - //set the error to the one on which we failed - SetLastError(error); - ODSEx("PacketOpenAdapter: CreateFile failed, Error=2,%d\n",error); - return NULL; - -} - -/*! - \brief Closes an adapter. - \param lpAdapter the pointer to the adapter to close. - - PacketCloseAdapter closes the given adapter and frees the associated ADAPTER structure -*/ -VOID PacketCloseAdapter(LPADAPTER lpAdapter) -{ - CloseHandle(lpAdapter->hFile); - SetEvent(lpAdapter->ReadEvent); - CloseHandle(lpAdapter->ReadEvent); - GlobalFreePtr(lpAdapter); -} - -/*! - \brief Allocates a _PACKET structure. - \return On succeess, the return value is the pointer to a _PACKET structure otherwise the - return value is NULL. - - The structure returned will be passed to the PacketReceivePacket() function to receive the - packets from the driver. - - \warning The Buffer field of the _PACKET structure is not set by this function. - The buffer \b must be allocated by the application, and associated to the PACKET structure - with a call to PacketInitPacket. -*/ -LPPACKET PacketAllocatePacket(void) -{ - - LPPACKET lpPacket; - lpPacket = (LPPACKET)GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,sizeof(PACKET)); - if (lpPacket == NULL) { - ODS("PacketAllocatePacket: GlobalAlloc Failed\n"); - return NULL; - } - return lpPacket; -} - -/*! - \brief Frees a _PACKET structure. - \param lpPacket The structure to free. - - \warning the user-allocated buffer associated with the _PACKET structure is not deallocated - by this function and \b must be explicitly deallocated by the programmer. - -*/ -VOID PacketFreePacket(LPPACKET lpPacket) -{ - GlobalFreePtr(lpPacket); -} - -/*! - \brief Initializes a _PACKET structure. - \param lpPacket The structure to initialize. - \param Buffer A pointer to a user-allocated buffer that will contain the captured data. - \param Length the length of the buffer. This is the maximum buffer size that will be - transferred from the driver to the application using a single read. - - \note the size of the buffer associated with the PACKET structure is a parameter that can sensibly - influence the performance of the capture process, since this buffer will contain the packets received - from the the driver. The driver is able to return several packets using a single read call - (see the PacketReceivePacket() function for details), and the number of packets transferable to the - application in a call is limited only by the size of the buffer associated with the PACKET structure - passed to PacketReceivePacket(). Therefore setting a big buffer with PacketInitPacket can noticeably - decrease the number of system calls, reducing the impcat of the capture process on the processor. -*/ - -VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length) -{ - lpPacket->Buffer = Buffer; - lpPacket->Length = Length; - lpPacket->ulBytesReceived = 0; - lpPacket->bIoComplete = FALSE; -} - -/*! - \brief Read data (packets or statistics) from the NPF driver. - \param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter from which - the data is received. - \param lpPacket Pointer to a PACKET structure that will contain the data. - \param Sync This parameter is deprecated and will be ignored. It is present for compatibility with - older applications. - \return If the function succeeds, the return value is nonzero. - - The data received with this function can be a group of packets or a static on the network traffic, - depending on the working mode of the driver. The working mode can be set with the PacketSetMode() - function. Give a look at that function if you are interested in the format used to return statistics - values, here only the normal capture mode will be described. - - The number of packets received with this function is variable. It depends on the number of packets - currently stored in the driver’s buffer, on the size of these packets and on the size of the buffer - associated to the lpPacket parameter. The following figure shows the format used by the driver to pass - packets to the application. - - \image html encoding.gif "method used to encode the packets" - - Packets are stored in the buffer associated with the lpPacket _PACKET structure. The Length field of - that structure is updated with the amount of data copied in the buffer. Each packet has a header - consisting in a bpf_hdr structure that defines its length and contains its timestamp. A padding field - is used to word-align the data in the buffer (to speed up the access to the packets). The bh_datalen - and bh_hdrlen fields of the bpf_hdr structures should be used to extract the packets from the buffer. - - Examples can be seen either in the TestApp sample application (see the \ref packetsamps page) provided - in the developer's pack, or in the pcap_read() function of wpcap. -*/ -BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) -{ - BOOLEAN res; - if ((int)AdapterObject->ReadTimeOut != -1) - WaitForSingleObject(AdapterObject->ReadEvent, (AdapterObject->ReadTimeOut==0)?INFINITE:AdapterObject->ReadTimeOut); - res = ReadFile(AdapterObject->hFile, lpPacket->Buffer, lpPacket->Length, &lpPacket->ulBytesReceived,NULL); - return res; -} - -/*! - \brief Sends one (or more) copies of a packet to the network. - \param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter that will - send the packets. - \param lpPacket Pointer to a PACKET structure with the packet to send. - \param Sync This parameter is deprecated and will be ignored. It is present for compatibility with - older applications. - \return If the function succeeds, the return value is nonzero. - - This function is used to send a raw packet to the network. 'Raw packet' means that the programmer - will have to include the protocol headers, since the packet is sent to the network 'as is'. - The CRC needs not to be calculated and put at the end of the packet, because it will be transparently - added by the network interface. - - The behavior of this function is influenced by the PacketSetNumWrites() function. With PacketSetNumWrites(), - it is possible to change the number of times a single write must be repeated. The default is 1, - i.e. every call to PacketSendPacket() will correspond to one packet sent to the network. If this number is - greater than 1, for example 1000, every raw packet written by the application will be sent 1000 times on - the network. This feature mitigates the overhead of the context switches and therefore can be used to generate - high speed traffic. It is particularly useful for tools that test networks, routers, and servers and need - to obtain high network loads. - The optimized sending process is still limited to one packet at a time: for the moment it cannot be used - to send a buffer with multiple packets. - - \note The ability to write multiple packets is currently present only in the Windows NTx version of the - packet driver. In Windows 95/98/ME it is emulated at user level in packet.dll. This means that an application - that uses the multiple write method will run in Windows 9x as well, but its performance will be very low - compared to the one of WindowsNTx. -*/ -BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync) -{ - DWORD BytesTransfered; - return WriteFile(AdapterObject->hFile,lpPacket->Buffer,lpPacket->Length,&BytesTransfered,NULL); -} - - -/*! - \brief Sends a buffer of packets to the network. - \param AdapterObject Pointer to an _ADAPTER structure identifying the network adapter that will - send the packets. - \param PacketBuff Pointer to buffer with the packets to send. - \param Size Size of the buffer pointed by the PacketBuff argument. - \param Sync if TRUE, the packets are sent respecting the timestamps. If FALSE, the packets are sent as - fast as possible - \return The amount of bytes actually sent. If the return value is smaller than the Size parameter, an - error occurred during the send. The error can be caused by a driver/adapter problem or by an - inconsistent/bogus packet buffer. - - This function is used to send a buffer of raw packets to the network. The buffer can contain an arbitrary - number of raw packets, each of which preceded by a dump_bpf_hdr structure. The dump_bpf_hdr is the same used - by WinPcap and libpcap to store the packets in a file, therefore sending a capture file is straightforward. - 'Raw packets' means that the sending application will have to include the protocol headers, since every packet - is sent to the network 'as is'. The CRC of the packets needs not to be calculated, because it will be - transparently added by the network interface. - - \note Using this function if more efficient than issuing a series of PacketSendPacket(), because the packets are - buffered in the kernel driver, so the number of context switches is reduced. - - \note When Sync is set to TRUE, the packets are synchronized in the kerenl with a high precision timestamp. - This requires a remarkable amount of CPU, but allows to send the packets with a precision of some microseconds - (depending on the precision of the performance counter of the machine). Such a precision cannot be reached - sending the packets separately with PacketSendPacket(). -*/ -INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) -{ - BOOLEAN Res; - DWORD BytesTransfered, TotBytesTransfered=0; - struct timeval BufStartTime; - LARGE_INTEGER StartTicks, CurTicks, TargetTicks, TimeFreq; - - - ODS("PacketSendPackets"); - - // Obtain starting timestamp of the buffer - BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec; - BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec; - - // Retrieve the reference time counters - QueryPerformanceCounter(&StartTicks); - QueryPerformanceFrequency(&TimeFreq); - - CurTicks.QuadPart = StartTicks.QuadPart; - - do{ - // Send the data to the driver - Res = DeviceIoControl(AdapterObject->hFile, - (Sync)?pBIOCSENDPACKETSSYNC:pBIOCSENDPACKETSNOSYNC, - (PCHAR)PacketBuff + TotBytesTransfered, - Size - TotBytesTransfered, - NULL, - 0, - &BytesTransfered, - NULL); - - TotBytesTransfered += BytesTransfered; - - // calculate the time interval to wait before sending the next packet - TargetTicks.QuadPart = StartTicks.QuadPart + - (LONGLONG) - ((((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec - BufStartTime.tv_sec) * 1000000 + - (((struct timeval*)((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) * - (TimeFreq.QuadPart) / 1000000; - - // Exit from the loop on termination or error - if(TotBytesTransfered >= Size || Res != TRUE) - break; - - // Wait until the time interval has elapsed - while( CurTicks.QuadPart <= TargetTicks.QuadPart ) - QueryPerformanceCounter(&CurTicks); - - } - while(TRUE); - - return TotBytesTransfered; -} - -/*! - \brief Defines the minimum amount of data that will be received in a read. - \param AdapterObject Pointer to an _ADAPTER structure - \param nbytes the minimum amount of data in the kernel buffer that will cause the driver to - release a read on this adapter. - \return If the function succeeds, the return value is nonzero. - - In presence of a large value for nbytes, the kernel waits for the arrival of several packets before - copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage, - i.e. better performance, which is a good setting for applications like sniffers. Vice versa, a small value - means that the kernel will copy the packets as soon as the application is ready to receive them. This is - suggested for real time applications (like, for example, a bridge) that need the better responsiveness from - the kernel. - - \b note: this function has effect only in Windows NTx. The driver for Windows 9x doesn't offer - this possibility, therefore PacketSetMinToCopy is implemented under these systems only for compatibility. -*/ - -BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes) -{ - DWORD BytesReturned; - return DeviceIoControl(AdapterObject->hFile,pBIOCSMINTOCOPY,&nbytes,4,NULL,0,&BytesReturned,NULL); -} - -/*! - \brief Sets the working mode of an adapter. - \param AdapterObject Pointer to an _ADAPTER structure. - \param mode The new working mode of the adapter. - \return If the function succeeds, the return value is nonzero. - - The device driver of WinPcap has 4 working modes: - - Capture mode (mode = PACKET_MODE_CAPT): normal capture mode. The packets transiting on the wire are copied - to the application when PacketReceivePacket() is called. This is the default working mode of an adapter. - - Statistical mode (mode = PACKET_MODE_STAT): programmable statistical mode. PacketReceivePacket() returns, at - precise intervals, statics values on the network traffic. The interval between the statistic samples is - by default 1 second but it can be set to any other value (with a 1 ms precision) with the - PacketSetReadTimeout() function. The data returned by PacketReceivePacket() when the adapter is in statistical - mode is shown in the following figure:

- \image html stats.gif "data structure returned by statistical mode" - Two 64-bit counters are provided: the number of packets and the amount of bytes that satisfy a filter - previously set with PacketSetBPF(). If no filter has been set, all the packets are counted. The counters are - encapsulated in a bpf_hdr structure, so that they will be parsed correctly by wpcap. Statistical mode has a - very low impact on system performance compared to capture mode. - - Dump mode (mode = PACKET_MODE_DUMP): the packets are dumped to disk by the driver, in libpcap format. This - method is much faster than saving the packets after having captured them. No data is returned - by PacketReceivePacket(). If the application sets a filter with PacketSetBPF(), only the packets that satisfy - this filter are dumped to disk. - - Statitical Dump mode (mode = PACKET_MODE_STAT_DUMP): the packets are dumped to disk by the driver, in libpcap - format, like in dump mode. PacketReceivePacket() returns, at precise intervals, statics values on the - network traffic and on the amount of data saved to file, in a way similar to statistical mode. - The data returned by PacketReceivePacket() when the adapter is in statistical dump mode is shown in - the following figure:

- \image html dump.gif "data structure returned by statistical dump mode" - Three 64-bit counters are provided: the number of packets accepted, the amount of bytes accepted and the - effective amount of data (including headers) dumped to file. If no filter has been set, all the packets are - dumped to disk. The counters are encapsulated in a bpf_hdr structure, so that they will be parsed correctly - by wpcap. - Look at the NetMeter example in the - WinPcap developer's pack to see how to use statistics mode. -*/ -BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode) -{ - DWORD BytesReturned; - return DeviceIoControl(AdapterObject->hFile,pBIOCSMODE,&mode,4,NULL,0,&BytesReturned,NULL); -} - -/*! - \brief Sets the name of the file that will receive the packet when the adapter is in dump mode. - \param AdapterObject Pointer to an _ADAPTER structure. - \param name the file name, in ASCII or UNICODE. - \param len the length of the buffer containing the name, in bytes. - \return If the function succeeds, the return value is nonzero. - - This function defines the file name that the driver will open to store the packets on disk when - it works in dump mode. The adapter must be in dump mode, i.e. PacketSetMode() should have been - called previously with mode = PACKET_MODE_DUMP. otherwise this function will fail. - If PacketSetDumpName was already invoked on the adapter pointed by AdapterObject, the driver - closes the old file and opens the new one. -*/ - -BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len) -{ - DWORD BytesReturned; - WCHAR *FileName; - BOOLEAN res; - WCHAR NameWithPath[1024]; - int TStrLen; - WCHAR *NamePos; - - if(((PUCHAR)name)[1]!=0 && len>1){ //ASCII - FileName=SChar2WChar(name); - len*=2; - } - else { //Unicode - FileName=name; - } - - TStrLen=GetFullPathName(FileName,1024,NameWithPath,&NamePos); - - len=TStrLen*2+2; //add the terminating null character - - // Try to catch malformed strings - if(len>2048){ - if(((PUCHAR)name)[1]!=0 && len>1) free(FileName); - return FALSE; - } - - res = DeviceIoControl(AdapterObject->hFile,pBIOCSETDUMPFILENAME,NameWithPath,len,NULL,0,&BytesReturned,NULL); - free(FileName); - return res; -} - -/*! - \brief Set the dump mode limits. - \param AdapterObject Pointer to an _ADAPTER structure. - \param maxfilesize The maximum dimension of the dump file, in bytes. 0 means no limit. - \param maxnpacks The maximum number of packets contained in the dump file. 0 means no limit. - \return If the function succeeds, the return value is nonzero. - - This function sets the limits after which the NPF driver stops to save the packets to file when an adapter - is in dump mode. This allows to limit the dump file to a precise number of bytes or packets, avoiding that - very long dumps fill the disk space. If both maxfilesize and maxnpacks are set, the dump is stopped when - the first of the two is reached. - - \note When a limit is reached, the dump is stopped, but the file remains opened. In order to flush - correctly the data and access the file consistently, you need to close the adapter with PacketCloseAdapter(). -*/ -BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks) -{ - DWORD BytesReturned; - UINT valbuff[2]; - - valbuff[0] = maxfilesize; - valbuff[1] = maxnpacks; - - return DeviceIoControl(AdapterObject->hFile, - pBIOCSETDUMPLIMITS, - valbuff, - sizeof valbuff, - NULL, - 0, - &BytesReturned, - NULL); -} - -/*! - \brief Returns the status of the kernel dump process, i.e. tells if one of the limits defined with PacketSetDumpLimits() was reached. - \param AdapterObject Pointer to an _ADAPTER structure. - \param sync if TRUE, the function blocks until the dump is finished, otherwise it returns immediately. - \return TRUE if the dump is ended, FALSE otherwise. - - PacketIsDumpEnded() informs the user about the limits that were set with a previous call to - PacketSetDumpLimits(). - - \warning If no calls to PacketSetDumpLimits() were performed or if the dump process has no limits - (i.e. if the arguments of the last call to PacketSetDumpLimits() were both 0), setting sync to TRUE will - block the application on this call forever. -*/ -BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync) -{ - DWORD BytesReturned; - int IsDumpEnded; - BOOLEAN res; - - if(sync) - WaitForSingleObject(AdapterObject->ReadEvent, INFINITE); - - res = DeviceIoControl(AdapterObject->hFile, - pBIOCISDUMPENDED, - NULL, - 0, - &IsDumpEnded, - 4, - &BytesReturned, - NULL); - - if(res == FALSE) return TRUE; // If the IOCTL returns an error we consider the dump finished - - return (BOOLEAN)IsDumpEnded; -} - -/*! - \brief Returns the notification event associated with the read calls on an adapter. - \param AdapterObject Pointer to an _ADAPTER structure. - \return The handle of the event that the driver signals when some data is available in the kernel buffer. - - The event returned by this function is signaled by the driver if: - - The adapter pointed by AdapterObject is in capture mode and an amount of data greater or equal - than the one set with the PacketSetMinToCopy() function is received from the network. - - the adapter pointed by AdapterObject is in capture mode, no data has been received from the network - but the the timeout set with the PacketSetReadTimeout() function has elapsed. - - the adapter pointed by AdapterObject is in statics mode and the the timeout set with the - PacketSetReadTimeout() function has elapsed. This means that a new statistic sample is available. - - In every case, a call to PacketReceivePacket() will return immediately. - The event can be passed to standard Win32 functions (like WaitForSingleObject or WaitForMultipleObjects) - to wait until the driver's buffer contains some data. It is particularly useful in GUI applications that - need to wait concurrently on several events. - -*/ -HANDLE PacketGetReadEvent(LPADAPTER AdapterObject) -{ - return AdapterObject->ReadEvent; -} - -/*! - \brief Sets the number of times a single packet written with PacketSendPacket() will be repeated on the network. - \param AdapterObject Pointer to an _ADAPTER structure. - \param nwrites Number of copies of a packet that will be physically sent by the interface. - \return If the function succeeds, the return value is nonzero. - - See PacketSendPacket() for details. -*/ -BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites) -{ - DWORD BytesReturned; - return DeviceIoControl(AdapterObject->hFile,pBIOCSWRITEREP,&nwrites,4,NULL,0,&BytesReturned,NULL); -} - -/*! - \brief Sets the timeout after which a read on an adapter returns. - \param AdapterObject Pointer to an _ADAPTER structure. - \param timeout indicates the timeout, in milliseconds, after which a call to PacketReceivePacket() on - the adapter pointed by AdapterObject will be released, also if no packets have been captured by the driver. - Setting timeout to 0 means no timeout, i.e. PacketReceivePacket() never returns if no packet arrives. - A timeout of -1 causes PacketReceivePacket() to always return immediately. - \return If the function succeeds, the return value is nonzero. - - \note This function works also if the adapter is working in statistics mode, and can be used to set the - time interval between two statistic reports. -*/ -BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout) -{ - DWORD BytesReturned; - int DriverTimeOut=-1; - - AdapterObject->ReadTimeOut=timeout; - - return DeviceIoControl(AdapterObject->hFile,pBIOCSRTIMEOUT,&DriverTimeOut,4,NULL,0,&BytesReturned,NULL); -} - -/*! - \brief Sets the size of the kernel-level buffer associated with a capture. - \param AdapterObject Pointer to an _ADAPTER structure. - \param dim New size of the buffer, in \b kilobytes. - \return The function returns TRUE if successfully completed, FALSE if there is not enough memory to - allocate the new buffer. - - When a new dimension is set, the data in the old buffer is discarded and the packets stored in it are - lost. - - Note: the dimension of the kernel buffer affects heavily the performances of the capture process. - An adequate buffer in the driver is able to keep the packets while the application is busy, compensating - the delays of the application and avoiding the loss of packets during bursts or high network activity. - The buffer size is set to 0 when an instance of the driver is opened: the programmer should remember to - set it to a proper value. As an example, wpcap sets the buffer size to 1MB at the beginning of a capture. -*/ -BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim) -{ - DWORD BytesReturned; - return DeviceIoControl(AdapterObject->hFile,pBIOCSETBUFFERSIZE,&dim,4,NULL,0,&BytesReturned,NULL); -} - -/*! - \brief Sets a kernel-level packet filter. - \param AdapterObject Pointer to an _ADAPTER structure. - \param fp Pointer to a filtering program that will be associated with this capture or monitoring - instance and that will be executed on every incoming packet. - \return This function returns TRUE if the filter is set successfully, FALSE if an error occurs - or if the filter program is not accepted after a safeness check by the driver. The driver performs - the check in order to avoid system crashes due to buggy or malicious filters, and it rejects non - conformat filters. - - This function associates a new BPF filter to the adapter AdapterObject. The filter, pointed by fp, is a - set of bpf_insn instructions. - - A filter can be automatically created by using the pcap_compile() function of wpcap. This function - converts a human readable text expression with the syntax of WinDump (see the manual of WinDump at - http://netgroup.polito.it/windump for details) into a BPF program. If your program doesn't link wpcap, but - you need to know the code of a particular filter, you can launch WinDump with the -d or -dd or -ddd - flags to obtain the pseudocode. - -*/ -BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp) -{ - DWORD BytesReturned; - return DeviceIoControl(AdapterObject->hFile,pBIOCSETF,(char*)fp->bf_insns,fp->bf_len*sizeof(struct bpf_insn),NULL,0,&BytesReturned,NULL); -} - -/*! - \brief Returns a couple of statistic values about the current capture session. - \param AdapterObject Pointer to an _ADAPTER structure. - \param s Pointer to a user provided bpf_stat structure that will be filled by the function. - \return If the function succeeds, the return value is nonzero. - - With this function, the programmer can know the value of two internal variables of the driver: - - - the number of packets that have been received by the adapter AdapterObject, starting at the - time in which it was opened with PacketOpenAdapter. - - the number of packets that have been dropped by the driver. A packet is dropped when the kernel - buffer associated with the adapter is full. -*/ -BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s) -{ - BOOLEAN Res; - DWORD BytesReturned; - struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications - - Res = DeviceIoControl(AdapterObject->hFile, - pBIOCGSTATS, - NULL, - 0, - &tmpstat, - sizeof(struct bpf_stat), - &BytesReturned, - NULL); - - // Copy only the first two values retrieved from the driver - s->bs_recv = tmpstat.bs_recv; - s->bs_drop = tmpstat.bs_drop; - - return Res; -} - -/*! - \brief Returns statistic values about the current capture session. Enhanced version of PacketGetStats(). - \param AdapterObject Pointer to an _ADAPTER structure. - \param s Pointer to a user provided bpf_stat structure that will be filled by the function. - \return If the function succeeds, the return value is nonzero. - - With this function, the programmer can retireve the sname values provided by PacketGetStats(), plus: - - - the number of drops by interface (not yet supported, always 0). - - the number of packets that reached the application, i.e that were accepted by the kernel filter and - that fitted in the kernel buffer. -*/ -BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s) -{ - BOOLEAN Res; - DWORD BytesReturned; - struct bpf_stat tmpstat; // We use a support structure to avoid kernel-level inconsistencies with old or malicious applications - - Res = DeviceIoControl(AdapterObject->hFile, - pBIOCGSTATS, - NULL, - 0, - &tmpstat, - sizeof(struct bpf_stat), - &BytesReturned, - NULL); - - s->bs_recv = tmpstat.bs_recv; - s->bs_drop = tmpstat.bs_drop; - s->ps_ifdrop = tmpstat.ps_ifdrop; - s->bs_capt = tmpstat.bs_capt; - - return Res; -} - -/*! - \brief Performs a query/set operation on an internal variable of the network card driver. - \param AdapterObject Pointer to an _ADAPTER structure. - \param Set Determines if the operation is a set (Set=TRUE) or a query (Set=FALSE). - \param OidData A pointer to a _PACKET_OID_DATA structure that contains or receives the data. - \return If the function succeeds, the return value is nonzero. - - \note not all the network adapters implement all the query/set functions. There is a set of mandatory - OID functions that is granted to be present on all the adapters, and a set of facultative functions, not - provided by all the cards (see the Microsoft DDKs to see which functions are mandatory). If you use a - facultative function, be careful to enclose it in an if statement to check the result. -*/ -BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData) -{ - //DWORD BytesReturned; - BOOLEAN Result = 0; - /*commented out since its broken & needs fixing*/ - /*Result=DeviceIoControl(AdapterObject->hFile,(DWORD) Set ? pBIOCSETOID : pBIOCQUERYOID, - OidData,sizeof(PACKET_OID_DATA)-1+OidData->Length,OidData, - sizeof(PACKET_OID_DATA)-1+OidData->Length,&BytesReturned,NULL);*/ - - // output some debug info - ODSEx("PacketRequest, OID=%d ", OidData->Oid); - ODSEx("Length=%d ", OidData->Length); - ODSEx("Set=%d ", Set); - ODSEx("Res=%d\n", Result); - - return Result; -} - -/*! - \brief Sets a hardware filter on the incoming packets. - \param AdapterObject Pointer to an _ADAPTER structure. - \param Filter The identifier of the filter. - \return If the function succeeds, the return value is nonzero. - - The filter defined with this filter is evaluated by the network card, at a level that is under the NPF - device driver. Here is a list of the most useful hardware filters (A complete list can be found in ntddndis.h): - - - NDIS_PACKET_TYPE_PROMISCUOUS: sets promiscuous mode. Every incoming packet is accepted by the adapter. - - NDIS_PACKET_TYPE_DIRECTED: only packets directed to the workstation's adapter are accepted. - - NDIS_PACKET_TYPE_BROADCAST: only broadcast packets are accepted. - - NDIS_PACKET_TYPE_MULTICAST: only multicast packets belonging to groups of which this adapter is a member are accepted. - - NDIS_PACKET_TYPE_ALL_MULTICAST: every multicast packet is accepted. - - NDIS_PACKET_TYPE_ALL_LOCAL: all local packets, i.e. NDIS_PACKET_TYPE_DIRECTED + NDIS_PACKET_TYPE_BROADCAST + NDIS_PACKET_TYPE_MULTICAST -*/ -BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter) -{ - BOOLEAN Status; - ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1); - PPACKET_OID_DATA OidData; - - OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength); - if (OidData == NULL) { - ODS("PacketSetHwFilter: GlobalAlloc Failed\n"); - return FALSE; - } - OidData->Oid=OID_GEN_CURRENT_PACKET_FILTER; - OidData->Length=sizeof(ULONG); - *((PULONG)OidData->Data)=Filter; - Status=PacketRequest(AdapterObject,TRUE,OidData); - GlobalFreePtr(OidData); - return Status; -} - -/*! - \brief Retrieve the list of available network adapters and their description. - \param pStr User allocated string that will be filled with the names of the adapters. - \param BufferSize Length of the buffer pointed by pStr. - \return If the function succeeds, the return value is nonzero. - - Usually, this is the first function that should be used to communicate with the driver. - It returns the names of the adapters installed on the system and supported by WinPcap. - After the names of the adapters, pStr contains a string that describes each of them. - - \b Warning: - the result of this function is obtained querying the registry, therefore the format - of the result in Windows NTx is different from the one in Windows 9x. Windows 9x uses the ASCII - encoding method to store a string, while Windows NTx uses UNICODE. After a call to PacketGetAdapterNames - in Windows 95x, pStr contains, in succession: - - a variable number of ASCII strings, each with the names of an adapter, separated by a "\0" - - a double "\0" - - a number of ASCII strings, each with the description of an adapter, separated by a "\0". The number - of descriptions is the same of the one of names. The fisrt description corresponds to the first name, and - so on. - - a double "\0". - - In Windows NTx, pStr contains: the names of the adapters, in UNICODE format, separated by a single UNICODE "\0" (i.e. 2 ASCII "\0"), a double UNICODE "\0", followed by the descriptions of the adapters, in ASCII format, separated by a single ASCII "\0" . The string is terminated by a double ASCII "\0". - - a variable number of UNICODE strings, each with the names of an adapter, separated by a UNICODE "\0" - - a double UNICODE "\0" - - a number of ASCII strings, each with the description of an adapter, separated by an ASCII "\0". - - a double ASCII "\0". -*/ - -BOOLEAN PacketGetAdapterNames(PTSTR pStr, PULONG BufferSize) -{ - HKEY LinkageKey, AdapKey; - DWORD RegKeySize = 0; - LONG Status; - ULONG Result; - PTSTR BpStr; - char *TTpStr; - char *DpStr; - char *DescBuf; - LPADAPTER adapter; - PPACKET_OID_DATA OidData; - int i = 0, k, rewind; - DWORD dim; - TCHAR AdapName[256]; - - ODSEx("PacketGetAdapterNames: BufferSize=%d\n",*BufferSize); - - OidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 512); - if (OidData == NULL) { - ODS("PacketGetAdapterNames: GlobalAlloc Failed\n"); - return FALSE; - } - - Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - TEXT("SYSTEM\\ControlSet001\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"), - 0, KEY_READ, &AdapKey); - - // Get the size to allocate for the original device names - while ((Result = RegEnumKey(AdapKey, i, AdapName, sizeof(AdapName)/2)) == ERROR_SUCCESS) { - Status = RegOpenKeyEx(AdapKey, AdapName,0, KEY_READ, &LinkageKey); - Status = RegOpenKeyExW(LinkageKey, L"Linkage",0, KEY_READ, &LinkageKey); - Status = RegQueryValueExW(LinkageKey, L"Export", NULL, NULL, NULL, &dim); - i++; - if (Status!=ERROR_SUCCESS) continue; - RegKeySize += dim; - } - - // Allocate the memory for the original device names - ODSEx("Need %d bytes for the names\n", RegKeySize+2); - BpStr = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, RegKeySize+2); - if (BpStr == NULL || RegKeySize > *BufferSize) { - ODS("PacketGetAdapterNames: GlobalAlloc Failed\n"); - GlobalFreePtr(OidData); - return FALSE; - } - k = 0; - i = 0; - - ODS("PacketGetAdapterNames: Cycling through the adapters:\n"); - - // Copy the names to the buffer - while ((Result = RegEnumKey(AdapKey, i, AdapName, sizeof(AdapName)/2)) == ERROR_SUCCESS) { - WCHAR UpperBindStr[64]; - - i++; - ODSEx(" %d) ", i); - - Status = RegOpenKeyEx(AdapKey,AdapName,0,KEY_READ,&LinkageKey); - Status = RegOpenKeyExW(LinkageKey,L"Linkage",0,KEY_READ,&LinkageKey); - - dim=sizeof(UpperBindStr); - Status=RegQueryValueExW(LinkageKey,L"UpperBind",NULL,NULL,(PUCHAR)UpperBindStr,&dim); - - ODSEx("UpperBind=%S ", UpperBindStr); - - if( Status!=ERROR_SUCCESS || _wcsicmp(UpperBindStr,L"NdisWan")==0 ){ - ODS("Name = SKIPPED\n"); - continue; - } - - dim=RegKeySize-k; - Status=RegQueryValueExW(LinkageKey,L"Export",NULL,NULL,(LPBYTE)BpStr+k,&dim); - if(Status!=ERROR_SUCCESS){ - ODS("Name = SKIPPED (error reading the key)\n"); - continue; - } - - ODSEx("Name = %S\n", (LPBYTE)BpStr+k); - - k+=dim-2; - } - - CloseHandle(AdapKey); - -#ifdef _DEBUG_TO_FILE - //dump BpStr for debug purposes - ODS("Dumping BpStr:"); - { - FILE *f; - f = fopen("winpcap_debug.txt", "a"); - for(i=0;i *BufferSize){ - // Input buffer too small - GlobalFreePtr(OidData); - GlobalFreePtr (BpStr); - GlobalFreePtr (DescBuf); - ODS("PacketGetAdapterNames: Input buffer too small!\n"); - return FALSE; - } - - // Create the device name - rewind=k; - memcpy(pStr+k,BpStr+i,16); - memcpy(pStr+k+8,TEXT("NPF_"),8); - i+=8; - k+=12; - while(BpStr[i-1]!=0){ - pStr[k++]=BpStr[i++]; - } - - // Open the adapter - adapter=PacketOpenAdapter(pStr+rewind); - if(adapter==NULL){ - k=rewind; - continue; - } - - // Retrieve the description - OidData->Oid = OID_GEN_VENDOR_DESCRIPTION; - OidData->Length = 256; - ZeroMemory(OidData->Data,256); - Status = PacketRequest(adapter,FALSE,OidData); - if(Status==0 || ((char*)OidData->Data)[0]==0){ - k=rewind; - continue; - } - - ODSEx("Adapter Description=%s\n\n",OidData->Data); - - // Copy the description - TTpStr=(char*)(OidData->Data); - while(*TTpStr!=0){ - *DpStr++=*TTpStr++; - } - *DpStr++=*TTpStr++; - - // Close the adapter - PacketCloseAdapter(adapter); - - } - *DpStr = 0; - - pStr[k++] = 0; - pStr[k] = 0; - - if ((ULONG)(DpStr - DescBuf + k) < *BufferSize) { - memcpy(pStr + k, DescBuf, DpStr - DescBuf); - } else { - GlobalFreePtr(OidData); - GlobalFreePtr(BpStr); - GlobalFreePtr(DescBuf); - ODS("\nPacketGetAdapterNames: ended with failure\n"); - return FALSE; - } - - GlobalFreePtr(OidData); - GlobalFreePtr(BpStr); - GlobalFreePtr(DescBuf); - ODS("\nPacketGetAdapterNames: ended correctly\n"); - return TRUE; - } - else{ - DWORD RegType; - - ODS("Adapters not found under SYSTEM\\ControlSet001\\Control\\Class. Using the TCP/IP bindings.\n"); - - GlobalFreePtr(BpStr); - Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - TEXT("SYSTEM\\ControlSet001\\Services\\Tcpip\\Linkage"), - 0, KEY_READ, &LinkageKey); - if (Status == ERROR_SUCCESS) { - // Retrieve the length of the key - Status = RegQueryValueEx(LinkageKey, TEXT("bind"), NULL, &RegType, NULL, &RegKeySize); - // Allocate the buffer - BpStr = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, RegKeySize + 2); - if (BpStr == NULL || RegKeySize > *BufferSize) { - GlobalFreePtr(OidData); - return FALSE; - } - Status = RegQueryValueEx(LinkageKey, TEXT("bind"), NULL, &RegType, (LPBYTE)BpStr, &RegKeySize); - RegCloseKey(LinkageKey); - } else { - //ODS("SYSTEM\\ControlSet001\\Control\\Class - RegKey not found.\n"); - ODS("SYSTEM\\ControlSet001\\Services\\Tcpip\\Linkage - RegKey not found.\n"); - } - if (Status == ERROR_SUCCESS) { - DescBuf = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, 4096); - if (DescBuf == NULL) { - GlobalFreePtr(BpStr); - GlobalFreePtr(OidData); - return FALSE; - } - DpStr = DescBuf; - for (i = 0, k = 0; BpStr[i] != 0 || BpStr[i+1] != 0; ) { - if (k + wcslen(BpStr + i) + 30 > *BufferSize) { - // Input buffer too small - GlobalFreePtr(OidData); - GlobalFreePtr(BpStr); - GlobalFreePtr(DescBuf); - return FALSE; - } - - ODS("\tCreating a device name - started.\n"); - - // Create the device name - rewind = k; - memcpy(pStr + k,BpStr + i,16); - memcpy(pStr + k + 8, TEXT("NPF_"), 8); - i += 8; - k += 12; - while (BpStr[i - 1] != 0) { - pStr[k++] = BpStr[i++]; - } - // Open the adapter - adapter = PacketOpenAdapter(pStr+rewind); - if (adapter == NULL) { - k = rewind; - continue; - } - // Retrieve the description - OidData->Oid = OID_GEN_VENDOR_DESCRIPTION; - OidData->Length = 256; - Status = PacketRequest(adapter, FALSE, OidData); - if (Status == 0 || ((char*)OidData->Data)[0] == 0) { - k = rewind; - ODS("\tCreating a device name - Retrieve the description.\n"); - continue; - } - - // Copy the description - TTpStr = (char*)(OidData->Data); - while (*TTpStr != 0){ - *DpStr++ = *TTpStr++; - } - *DpStr++ = *TTpStr++; - // Close the adapter - PacketCloseAdapter(adapter); - - ODS("\tCreating a device name - completed.\n"); - } - *DpStr = 0; - - pStr[k++] = 0; - pStr[k] = 0; - - if ((ULONG)(DpStr - DescBuf + k) < *BufferSize) { - memcpy(pStr + k, DescBuf, DpStr-DescBuf); - } else { - GlobalFreePtr(OidData); - GlobalFreePtr(BpStr); - GlobalFreePtr(DescBuf); - return FALSE; - } - - GlobalFreePtr(OidData); - GlobalFreePtr(BpStr); - GlobalFreePtr(DescBuf); - ODS("PacketGetAdapterNames() returning TRUE\n"); - return TRUE; - } else { - 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); - ODS("Cannot find the TCP/IP bindings\n"); - return FALSE; - } - } -} - -/*! - \brief Returns comprehensive information the addresses of an adapter. - \param AdapterName String that contain _ADAPTER structure. - \param buffer A user allocated array of npf_if_addr that will be filled by the function. - \param NEntries Size of the array (in npf_if_addr). - \return If the function succeeds, the return value is nonzero. - - This function grabs from the registry information like the IP addresses, the netmasks - and the broadcast addresses of an interface. The buffer passed by the user is filled with - npf_if_addr structures, each of which contains the data for a single address. If the buffer - is full, the reaming addresses are dropeed, therefore set its dimension to sizeof(npf_if_addr) - if you want only the first address. -*/ - -BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries) -{ - char *AdapterNameA; - WCHAR *AdapterNameU; - WCHAR *ifname; - HKEY SystemKey; - HKEY InterfaceKey; - HKEY ParametersKey; - HKEY TcpIpKey; - HKEY UnderTcpKey; - LONG status; - WCHAR String[1024+1]; - DWORD RegType; - ULONG BufLen; - DWORD DHCPEnabled; - struct sockaddr_in *TmpAddr, *TmpBroad; - LONG naddrs,nmasks,StringPos; - DWORD ZeroBroadcast; - - AdapterNameA = (char*)AdapterName; - if(AdapterNameA[1] != 0) { //ASCII - AdapterNameU = SChar2WChar(AdapterNameA); - AdapterName = AdapterNameU; - } else { //Unicode - AdapterNameU = NULL; - } - ifname = wcsrchr(AdapterName, '\\'); - if (ifname == NULL) - ifname = AdapterName; - else - ifname++; - if (wcsncmp(ifname, L"NPF_", 4) == 0) - ifname += 4; - - if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, - TEXT("SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces"), - 0, KEY_READ, &UnderTcpKey) == ERROR_SUCCESS) - { - status = RegOpenKeyExW(UnderTcpKey,ifname,0,KEY_READ,&TcpIpKey); - if (status != ERROR_SUCCESS) { - RegCloseKey(UnderTcpKey); - goto fail; - } - } - else - { - - // Query the registry key with the interface's adresses - status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - TEXT("SYSTEM\\ControlSet001\\Services"), - 0,KEY_READ,&SystemKey); - if (status != ERROR_SUCCESS) - goto fail; - status = RegOpenKeyExW(SystemKey,ifname,0,KEY_READ,&InterfaceKey); - if (status != ERROR_SUCCESS) { - RegCloseKey(SystemKey); - goto fail; - } - RegCloseKey(SystemKey); - status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey); - if (status != ERROR_SUCCESS) { - RegCloseKey(InterfaceKey); - goto fail; - } - RegCloseKey(InterfaceKey); - status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey); - if (status != ERROR_SUCCESS) { - RegCloseKey(ParametersKey); - goto fail; - } - RegCloseKey(ParametersKey); - BufLen = sizeof String; - } - - BufLen = 4; - /* Try to detect if the interface has a zero broadcast addr */ - status=RegQueryValueEx(TcpIpKey,TEXT("UseZeroBroadcast"),NULL,&RegType,(LPBYTE)&ZeroBroadcast,&BufLen); - if (status != ERROR_SUCCESS) - ZeroBroadcast=0; - - BufLen = 4; - /* See if DHCP is used by this system */ - status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen); - if (status != ERROR_SUCCESS) - DHCPEnabled=0; - - - /* Retrieve the adrresses */ - if(DHCPEnabled){ - - BufLen = sizeof String; - // Open the key with the addresses - status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); - if (status != ERROR_SUCCESS) { - RegCloseKey(TcpIpKey); - goto fail; - } - - // scan the key to obtain the addresses - StringPos = 0; - for(naddrs = 0;naddrs <* NEntries;naddrs++){ - TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress); - - if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ - TmpAddr->sin_family = AF_INET; - - TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast); - TmpBroad->sin_family = AF_INET; - if(ZeroBroadcast==0) - TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255 - else - TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0 - - while(*(String + StringPos) != 0)StringPos++; - StringPos++; - - if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) - break; - } - else break; - } - - BufLen = sizeof String; - // Open the key with the netmasks - status = RegQueryValueEx(TcpIpKey,TEXT("DhcpSubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen); - if (status != ERROR_SUCCESS) { - RegCloseKey(TcpIpKey); - goto fail; - } - - // scan the key to obtain the masks - StringPos = 0; - for(nmasks = 0;nmasks < *NEntries;nmasks++){ - TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask); - - if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ - TmpAddr->sin_family = AF_INET; - - while(*(String + StringPos) != 0)StringPos++; - StringPos++; - - if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) - break; - } - else break; - } - - // The number of masks MUST be equal to the number of adresses - if(nmasks != naddrs){ - RegCloseKey(TcpIpKey); - goto fail; - } - - } - else{ - - BufLen = sizeof String; - // Open the key with the addresses - status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); - if (status != ERROR_SUCCESS) { - RegCloseKey(TcpIpKey); - goto fail; - } - - // scan the key to obtain the addresses - StringPos = 0; - for(naddrs = 0;naddrs < *NEntries;naddrs++){ - TmpAddr = (struct sockaddr_in *) &(buffer[naddrs].IPAddress); - - if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ - TmpAddr->sin_family = AF_INET; - - TmpBroad = (struct sockaddr_in *) &(buffer[naddrs].Broadcast); - TmpBroad->sin_family = AF_INET; - if(ZeroBroadcast==0) - TmpBroad->sin_addr.S_un.S_addr = 0xffffffff; // 255.255.255.255 - else - TmpBroad->sin_addr.S_un.S_addr = 0; // 0.0.0.0 - - while(*(String + StringPos) != 0)StringPos++; - StringPos++; - - if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) - break; - } - else break; - } - - BufLen = sizeof String; - // Open the key with the netmasks - status = RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType,(LPBYTE)String,&BufLen); - if (status != ERROR_SUCCESS) { - RegCloseKey(TcpIpKey); - goto fail; - } - - // scan the key to obtain the masks - StringPos = 0; - for(nmasks = 0;nmasks <* NEntries;nmasks++){ - TmpAddr = (struct sockaddr_in *) &(buffer[nmasks].SubnetMask); - - if((TmpAddr->sin_addr.S_un.S_addr = inet_addrU(String + StringPos))!= -1){ - TmpAddr->sin_family = AF_INET; - - while(*(String + StringPos) != 0)StringPos++; - StringPos++; - - if(*(String + StringPos) == 0 || (StringPos * sizeof (WCHAR)) >= BufLen) - break; - } - else break; - } - - // The number of masks MUST be equal to the number of adresses - if(nmasks != naddrs){ - RegCloseKey(TcpIpKey); - goto fail; - } - - } - - *NEntries = naddrs + 1; - - RegCloseKey(TcpIpKey); - - if (status != ERROR_SUCCESS) { - goto fail; - } - - - if (AdapterNameU != NULL) - free(AdapterNameU); - return TRUE; - -fail: - if (AdapterNameU != NULL) - free(AdapterNameU); - return FALSE; -} - -/*! - \brief Returns the IP address and the netmask of an adapter. - \param AdapterName String that contain _ADAPTER structure. - \param netp Pointer to a variable that will receive the IP address of the adapter. - \param maskp Pointer to a variable that will receive the netmask of the adapter. - \return If the function succeeds, the return value is nonzero. - - \note this function is obsolete and is maintained for backward compatibility. Use PacketGetNetInfoEx() instead. -*/ - -BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp) -{ - char *AdapterNameA; - WCHAR *AdapterNameU; - WCHAR *ifname; - HKEY SystemKey; - HKEY InterfaceKey; - HKEY ParametersKey; - HKEY TcpIpKey; - LONG status; - WCHAR String[1024+1]; - DWORD RegType; - ULONG BufLen; - DWORD DHCPEnabled; - ULONG TAddr,i; - - AdapterNameA = (char*)AdapterName; - if(AdapterNameA[1] != 0) { //ASCII - AdapterNameU = SChar2WChar(AdapterNameA); - AdapterName = AdapterNameU; - } else { //Unicode - AdapterNameU = NULL; - } - ifname = wcsrchr(AdapterName, '\\'); - if (ifname == NULL) - ifname = AdapterName; - else - ifname++; - if (wcsncmp(ifname, L"NPF_", 4) == 0) - ifname += 4; - status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - TEXT("SYSTEM\\ControlSet001\\Services"), - 0,KEY_READ,&SystemKey); - if (status != ERROR_SUCCESS) - goto fail; - status = RegOpenKeyExW(SystemKey,ifname,0,KEY_READ,&InterfaceKey); - if (status != ERROR_SUCCESS) { - RegCloseKey(SystemKey); - goto fail; - } - RegCloseKey(SystemKey); - status = RegOpenKeyEx(InterfaceKey,TEXT("Parameters"),0,KEY_READ,&ParametersKey); - if (status != ERROR_SUCCESS) { - RegCloseKey(InterfaceKey); - goto fail; - } - RegCloseKey(InterfaceKey); - status = RegOpenKeyEx(ParametersKey,TEXT("TcpIp"),0,KEY_READ,&TcpIpKey); - if (status != ERROR_SUCCESS) { - RegCloseKey(ParametersKey); - goto fail; - } - RegCloseKey(ParametersKey); - - BufLen = 4; - /* See if DHCP is used by this system */ - status=RegQueryValueEx(TcpIpKey,TEXT("EnableDHCP"),NULL,&RegType,(LPBYTE)&DHCPEnabled,&BufLen); - if (status != ERROR_SUCCESS) - DHCPEnabled=0; - - - /* Retrieve the netmask */ - if(DHCPEnabled){ - - BufLen = sizeof String; - status = RegQueryValueEx(TcpIpKey,TEXT("DhcpIPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); - if (status != ERROR_SUCCESS) { - RegCloseKey(TcpIpKey); - goto fail; - } - - TAddr = inet_addrU(String); - // swap bytes for backward compatibility - for(i=0;i<4;i++){ - *((char*)netp+i) = *((char*)&TAddr+3-i); - } - - BufLen = sizeof String; - status=RegQueryValueEx(TcpIpKey,TEXT("DHCPSubnetMask"),NULL,&RegType, - (LPBYTE)String,&BufLen); - - TAddr = inet_addrU(String); - // swap bytes for backward compatibility - for(i=0;i<4;i++){ - *((char*)maskp+i) = *((char*)&TAddr+3-i); - } - - - } - else{ - - BufLen = sizeof String; - status = RegQueryValueEx(TcpIpKey,TEXT("IPAddress"),NULL,&RegType,(LPBYTE)String,&BufLen); - if (status != ERROR_SUCCESS) { - RegCloseKey(TcpIpKey); - goto fail; - } - - TAddr = inet_addrU(String); - // swap bytes for backward compatibility - for(i=0;i<4;i++){ - *((char*)netp+i) = *((char*)&TAddr+3-i); - } - - BufLen = sizeof String; - status=RegQueryValueEx(TcpIpKey,TEXT("SubnetMask"),NULL,&RegType, - (LPBYTE)String,&BufLen); - - TAddr = inet_addrU(String); - // swap bytes for backward compatibility - for(i=0;i<4;i++){ - *((char*)maskp+i) = *((char*)&TAddr+3-i); - } - - - } - - if (status != ERROR_SUCCESS) { - RegCloseKey(TcpIpKey); - goto fail; - } - - - if (AdapterNameU != NULL) - free(AdapterNameU); - return TRUE; - -fail: - if (AdapterNameU != NULL) - free(AdapterNameU); - return FALSE; -} - -/* @} */ diff --git a/reactos/dll/win32/packet/include/packet32.h b/reactos/dll/win32/packet/include/packet32.h deleted file mode 100644 index fad5b532afe..00000000000 --- a/reactos/dll/win32/packet/include/packet32.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 1999, 2000 - * Politecnico di Torino. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the Politecnico - * di Torino, and its contributors.'' Neither the name of - * the University nor the names of its contributors may be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/** @ingroup packetapi - * @{ - */ - -/** @defgroup packet32h Packet.dll definitions and data structures - * Packet32.h contains the data structures and the definitions used by packet.dll. - * The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included - * by the applications that use the functions of this library - * @{ - */ - -#ifndef __PACKET32 -#define __PACKET32 - -#include - -// Working modes -#define PACKET_MODE_CAPT 0x0 ///< Capture mode -#define PACKET_MODE_STAT 0x1 ///< Statistical mode -#define PACKET_MODE_DUMP 0x10 ///< Dump mode -#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode - -// ioctls -#define FILE_DEVICE_PROTOCOL 0x8000 - -#define IOCTL_PROTOCOL_STATISTICS CTL_CODE(FILE_DEVICE_PROTOCOL, 2 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_RESET CTL_CODE(FILE_DEVICE_PROTOCOL, 3 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_READ CTL_CODE(FILE_DEVICE_PROTOCOL, 4 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_WRITE CTL_CODE(FILE_DEVICE_PROTOCOL, 5 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_PROTOCOL_MACNAME CTL_CODE(FILE_DEVICE_PROTOCOL, 6 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_OPEN CTL_CODE(FILE_DEVICE_PROTOCOL, 7 , METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_CLOSE CTL_CODE(FILE_DEVICE_PROTOCOL, 8 , METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define pBIOCSETBUFFERSIZE 9592 ///< IOCTL code: set kernel buffer size. -#define pBIOCSETF 9030 ///< IOCTL code: set packet filtering program. -#define pBIOCGSTATS 9031 ///< IOCTL code: get the capture stats. -#define pBIOCSRTIMEOUT 7416 ///< IOCTL code: set the read timeout. -#define pBIOCSMODE 7412 ///< IOCTL code: set working mode. -#define pBIOCSWRITEREP 7413 ///< IOCTL code: set number of physical repetions of every packet written by the app. -#define pBIOCSMINTOCOPY 7414 ///< IOCTL code: set minimum amount of data in the kernel buffer that unlocks a read call. -#define pBIOCSETOID 2147483648 ///< IOCTL code: set an OID value. -#define pBIOCQUERYOID 2147483652 ///< IOCTL code: get an OID value. -#define pATTACHPROCESS 7117 ///< IOCTL code: attach a process to the driver. Used in Win9x only. -#define pDETACHPROCESS 7118 ///< IOCTL code: detach a process from the driver. Used in Win9x only. -#define pBIOCSETDUMPFILENAME 9029 ///< IOCTL code: set the name of a the file used by kernel dump mode. -#define pBIOCEVNAME 7415 ///< IOCTL code: get the name of the event that the driver signals when some data is present in the buffer. -#define pBIOCSENDPACKETSNOSYNC 9032 ///< IOCTL code: Send a buffer containing multiple packets to the network, ignoring the timestamps associated with the packets. -#define pBIOCSENDPACKETSSYNC 9033 ///< IOCTL code: Send a buffer containing multiple packets to the network, respecting the timestamps associated with the packets. -#define pBIOCSETDUMPLIMITS 9034 ///< IOCTL code: Set the dump file limits. See the PacketSetDumpLimits() function. -#define pBIOCISDUMPENDED 7411 ///< IOCTL code: Get the status of the kernel dump process. See the PacketIsDumpEnded() function. - -#define pBIOCSTIMEZONE 7471 ///< IOCTL code: set time zone. Used in Win9x only. - - -/// Alignment macro. Defines the alignment size. -#define Packet_ALIGNMENT sizeof(int) -/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT. -#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1)) - -/*! - \brief Network type structure. - - This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed. -*/ -typedef struct NetType -{ - UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information) - UINT LinkSpeed; ///< The speed of the network in bits per second -}NetType; - - -//some definitions stolen from libpcap - -#ifndef BPF_MAJOR_VERSION - -/*! - \brief A BPF pseudo-assembly program. - - The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet. -*/ -struct bpf_program { - UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow. - struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program. -}; - -/*! - \brief A single BPF pseudo-instruction. - - bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver. -*/ -struct bpf_insn { - USHORT code; ///< Instruction type and addressing mode. - UCHAR jt; ///< Jump if true - UCHAR jf; ///< Jump if false - int k; ///< Generic field used for various purposes. -}; - -/*! - \brief Structure that contains a couple of statistics values on the current capture. - - It is used by packet.dll to return statistics about a capture session. -*/ -struct bpf_stat { - UINT bs_recv; ///< Number of packets that the driver received from the network adapter - ///< from the beginning of the current capture. This value includes the packets - ///< lost by the driver. - UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture. - ///< Basically, a packet is lost when the the buffer of the driver is full. - ///< In this situation the packet cannot be stored and the driver rejects it. - UINT ps_ifdrop; ///< drops by interface. XXX not yet supported - UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and - ///< thus reach the application. -}; - -/*! - \brief Packet header. - - This structure defines the header associated with every packet delivered to the application. -*/ -struct bpf_hdr { - struct timeval bh_tstamp; ///< The timestamp associated with the captured packet. - ///< It is stored in a TimeVal structure. - UINT bh_caplen; ///< Length of captured portion. The captured portion can be different - ///< from the original packet, because it is possible (with a proper filter) - ///< to instruct the driver to capture only a portion of the packets. - UINT bh_datalen; ///< Original length of packet - USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases, - ///< a padding could be added between the end of this structure and the packet - ///< data for performance reasons. This filed can be used to retrieve the actual data - ///< of the packet. -}; - -/*! - \brief Dump packet header. - - This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets(). - It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a - packet in a dump file. This makes straightforward sending WinPcap dump files to the network. -*/ -struct dump_bpf_hdr{ - struct timeval ts; ///< Time stamp of the packet - UINT caplen; ///< Length of captured portion. The captured portion can smaller than the - ///< the original packet, because it is possible (with a proper filter) to - ///< instruct the driver to capture only a portion of the packets. - UINT len; ///< Length of the original packet (off wire). -}; - - -#endif - -#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices -#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links -#define NMAX_PACKET 65535 - -/*! - \brief Describes a network adapter. - - This structure is the most important for the functioning of packet.dll, but the great part of its fields - should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters -*/ -typedef struct _ADAPTER { - HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver. - CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened. - int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated - ///< on the wire. - HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter. - ///< It can be passed to standard Win32 functions (like WaitForSingleObject - ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some - ///< data. It is particularly useful in GUI applications that need to wait - ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy() - ///< function can be used to define the minimum amount of data in the kernel buffer - ///< that will cause the event to be signalled. - - UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and - ///< ReadEvent will be signaled, also if no packets were captured -} ADAPTER, *LPADAPTER; - -/*! - \brief Structure that contains a group of packets coming from the driver. - - This structure defines the header associated with every packet delivered to the application. -*/ -typedef struct _PACKET { - HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications. - OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications. - PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for - ///< details about the organization of the data in this buffer - UINT Length; ///< Length of the buffer - DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data - ///< received by the last call to PacketReceivePacket() - BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications. -} PACKET, *LPPACKET; - -/*! - \brief Structure containing an OID request. - - It is used by the PacketRequest() function to send an OID to the interface card driver. - It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address, - the list of the multicast groups defined on it, and so on. -*/ -struct _PACKET_OID_DATA { - ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h - ///< for a complete list of valid codes. - ULONG Length; ///< Length of the data field - UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received - ///< from the adapter. -}; -typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA; - -/*! - \brief Addresses of a network adapter. - - This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with - an adapter. -*/ -typedef struct npf_if_addr { - struct sockaddr IPAddress; ///< IP address. - struct sockaddr SubnetMask; ///< Netmask for that address. - struct sockaddr Broadcast; ///< Broadcast address. -}npf_if_addr; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @} - */ - -//--------------------------------------------------------------------------- -// FUNCTIONS -//--------------------------------------------------------------------------- - -PCHAR PacketGetVersion(); -BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes); -BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites); -BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode); -BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout); -BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp); -BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s); -BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s); -BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim); -BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type); -LPADAPTER PacketOpenAdapter(LPTSTR AdapterName); -BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync); -INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync); -LPPACKET PacketAllocatePacket(void); -VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length); -VOID PacketFreePacket(LPPACKET lpPacket); -BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync); -BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter); -BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize); -BOOLEAN PacketGetNetInfo(LPTSTR AdapterName, PULONG netp, PULONG maskp); -BOOLEAN PacketGetNetInfoEx(LPTSTR AdapterName, npf_if_addr* buffer, PLONG NEntries); -BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData); -HANDLE PacketGetReadEvent(LPADAPTER AdapterObject); -BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len); -BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks); -BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync); -BOOL PacketStopDriver(); -VOID PacketCloseAdapter(LPADAPTER lpAdapter); - -#ifdef __cplusplus -} -#endif - -#endif //__PACKET32 diff --git a/reactos/dll/win32/packet/packet.def b/reactos/dll/win32/packet/packet.def deleted file mode 100644 index bba1a4c4e35..00000000000 --- a/reactos/dll/win32/packet/packet.def +++ /dev/null @@ -1,34 +0,0 @@ -LIBRARY packet - -DESCRIPTION 'Packet driver dll' - -EXPORTS - PacketLibraryVersion - PacketGetVersion - PacketOpenAdapter - PacketSendPacket - PacketSendPackets - PacketAllocatePacket - PacketInitPacket - PacketFreePacket - PacketReceivePacket - PacketCloseAdapter - PacketSetHwFilter - PacketGetAdapterNames - PacketRequest - PacketSetBuff - PacketSetBpf - PacketGetStats - PacketGetStatsEx - PacketGetNetType - PacketSetReadTimeout - PacketSetMode - PacketSetNumWrites - PacketGetNetInfo - PacketGetNetInfoEx - PacketSetMinToCopy - PacketGetReadEvent - PacketStopDriver - PacketSetDumpName - PacketSetDumpLimits - PacketIsDumpEnded diff --git a/reactos/dll/win32/packet/packet.rc b/reactos/dll/win32/packet/packet.rc deleted file mode 100644 index bfa5d124c3e..00000000000 --- a/reactos/dll/win32/packet/packet.rc +++ /dev/null @@ -1,44 +0,0 @@ -#include "resource.h" - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,3,0,33 - PRODUCTVERSION 2,3,0,33 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "WinPcap low level packet library\0" - VALUE "CompanyName", "Politecnico di Torino\0" - VALUE "FileDescription", "Packet\0" - VALUE "FileVersion", "2, 3, 0, 33\0" - VALUE "InternalName", "Packet\0" - VALUE "LegalCopyright", "Copyright © 1999-2002\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "Packet.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "WinPcap low level packet library\0" - VALUE "ProductVersion", "2, 3, 0, 33\0" - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - diff --git a/reactos/dll/win32/packet/resource.h b/reactos/dll/win32/packet/resource.h deleted file mode 100644 index 6d5e116e031..00000000000 --- a/reactos/dll/win32/packet/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by version.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/reactos/dll/win32/packet/trace.c b/reactos/dll/win32/packet/trace.c deleted file mode 100644 index 4ff6a14b3a5..00000000000 --- a/reactos/dll/win32/packet/trace.c +++ /dev/null @@ -1,53 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Diagnostic Trace -// -#include -#include -#include -//#include -#include "trace.h" - -#ifdef _DEBUG - -#undef THIS_FILE -//static char THIS_FILE[] = __FILE__; - -void _DebugBreak(void) -{ - DebugBreak(); -} - -//void Trace(TCHAR* lpszFormat, ...) -void Trace(char* lpszFormat, ...) -{ - va_list args; - int nBuf; - char szBuffer[512]; - - va_start(args, lpszFormat); - nBuf = _vsnprintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), lpszFormat, args); - OutputDebugStringA(szBuffer); - // was there an error? was the expanded string too long? - //ASSERT(nBuf >= 0); - va_end(args); -} - -void Assert(void* assert, const char* file, int line, void* msg) -{ - if (msg == NULL) { - printf("ASSERT -- %s occured on line %u of file %s.\n", - (CHAR *)assert, line, file); - } else { - printf("ASSERT -- %s occured on line %u of file %s: Message = %s.\n", - (CHAR *)assert, line, file, (CHAR *)msg); - } -} - -#else - -//void Trace(TCHAR* lpszFormat, ...) { }; -void Trace(char* lpszFormat, ...) { }; -void Assert(void* assert, const char* file, int line, void* msg) { }; - -#endif //_DEBUG -///////////////////////////////////////////////////////////////////////////// diff --git a/reactos/dll/win32/packet/trace.h b/reactos/dll/win32/packet/trace.h deleted file mode 100644 index a227b166022..00000000000 --- a/reactos/dll/win32/packet/trace.h +++ /dev/null @@ -1,62 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Diagnostic Trace -// -#ifndef __TRACE_H__ -#define __TRACE_H__ - -#ifdef _DEBUG - -#ifdef _X86_ -#define BreakPoint() _asm { int 3h } -#else -#define BreakPoint() _DebugBreak() -#endif - -#ifndef ASSERT -#define ASSERT(exp) \ -{ \ - if (!(exp)) { \ - Assert(#exp, __FILE__, __LINE__, NULL); \ - BreakPoint(); \ - } \ -} \ - -#define ASSERTMSG(exp, msg) \ -{ \ - if (!(exp)) { \ - Assert(#exp, __FILE__, __LINE__, msg); \ - BreakPoint(); \ - } \ -} -#endif - -//============================================================================= -// MACRO: TRACE() -//============================================================================= - -#define TRACE Trace - - -#else // _DEBUG - -//============================================================================= -// Define away MACRO's ASSERT() and TRACE() in non debug builds -//============================================================================= - -#ifndef ASSERT -#define ASSERT(exp) -#define ASSERTMSG(exp, msg) -#endif - -#define TRACE 0 ? (void)0 : Trace - -#endif // !_DEBUG - - -void Assert(void* assert, const char* file, int line, void* msg); -//void Trace(TCHAR* lpszFormat, ...); -void Trace(char* lpszFormat, ...); - - -#endif // __TRACE_H__ -/////////////////////////////////////////////////////////////////////////////